在PostgreSQL中使用多个模式时无法找到表

问题描述 投票:1回答:1

WPF PostgreSQL 11.1

Npgsql.PostgresException:'42P01:关系“testme”不存在'

当尝试使用具有多个模式的PostgreSQL数据库时,我在App.config中定义了以下连接字符串。请注意,唯一的区别在于SearchPath:

 <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql, Version=4.0.4.0, Culture=neutral" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <clear />
    <add name="localconnection" providerName="Npgsql" connectionString="Server=127.0.0.1;Port=5432;Database=chaos;User Id=postgres;Password=****;Searchpath=nova" />
    <add name="phoenixconnection" providerName="Npgsql" connectionString="Server=127.0.0.1;Port=5432;Database=chaos;User Id=postgres;Password=****;SearchPath=phoenix;" />
  </connectionStrings>

使用NuGet安装Npgsql数据提供程序:运行时版本:v4.0.30319版本:4.0.4.0

在PostgreSQL中,在Phoenix模式中:

CREATE TABLE phoenix.testme
(
    name text COLLATE pg_catalog."default" NOT NULL
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE phoenix.testme
    OWNER to postgres;

使用PgAdmin,显示testme表没有问题:

select * from phoenix.testme;

我已使用上述连接字符串配置了WCF服务。使用PetaPoco,我编写以下脚本:

public string SayHello()
    {
        string msg;
        using (var db = new chaosDB("phoenixconnection"))
        {
            var m = db.ExecuteScalar<string>("select version()");
            msg = string.Format("Hello from {0}", m);

            m = db.ExecuteScalar<string>("select current_schema");
            msg = string.Format("{0} Current Schema is {1}", msg, m);

            var ss = db.ExecuteScalar<string>("show search_path");


            var s = db.Fetch<string>("select * from testme"); <---THIS FAILS!
            msg = string.Format("{0} I Am {1}", msg, m);

        }
        return msg;
    }

当我收到上述错误时,一切正常,直到执行“select * from testme”。注意:“show search_path”中的ss正确返回“phoenix”

我究竟做错了什么?我如何让它工作?

最感谢任何帮助?

postgresql npgsql petapoco
1个回答
0
投票

经过多次努力之后,答案变得不言而喻了。首先,我重置了数据库中的search_path。这没有用。然后我用PetaPoco重建了POCO,并很快发现不仅没有创建新表“testme”,也没有任何POCO。因此,检查,PetaPoco中的Database.tt文件显示它具有错误的ConnectionStringName。将ConnectionStringName更改为“phoenixconnection”允许构建POCO,但再次找不到“testme”表。

然后错误变得很明显,如上所述,“phoenixconnection”和“localconnection”都指向同一个端口。从以前的开发,我使PostgreSQL v10.1在与新的PostgreSQL v11.1相同的端口上运行。显然,第一个PostgreSQL v10.1正在接收连接(而不是新的PostgreSQL v11.1)。

转到服务(services.msc)并关闭v10.1并运行Database.TT现在给出了错误:System.InvalidOperationException:Sequence包含多个匹配元素

显然v10.1(我用于开发)只有一个模式,但v11.1有多个模式。我接受错误消息表示PetaPoco看到多个具有相同表名的表 - 即,它没有区分模式。

所以,问题现在已经解决了。

  1. 修复端口!较旧的单一模式PostgreSQL v10.1保留在端口:5432。较新的多模式PostgreSQL保留在端口5433上.v10.1将用于POCO。
  2. 修复WCF的App.config中的连接字符串,以便在运行时,WCF将使用较新的v11.1。生成后,单独离开POCO并在WCF文件中引用它们。

显然,PetaPoco只能在生成POCO时使用一个模式,但在运行时会从WCF的App.Config中读取连接字符串以执行其查询等(因此在App.config中,Database.TT所在的位置) ,将PetaPoco指向仅具有单个模式的“开发”数据库,但在WCF环境中,将连接字符串指向具有多个模式的新数据库。连接字符串的SearchPath在通过Npgsql运行时受到尊重。

如果PetaPoco能够在多模式环境中生成POCO特定的模式会很好,但此刻,我猜它不能:(

附录注意:事实证明PostgreSQL的给定实例可以有多个DATABASES。因此,如果Npgsql的连接字符串特定于开发数据库 - 即,只有一个模式的数据库 - 那么在开发期间,PetaPoco可以很好地创建POCO。然后,可以将这些POCO直接用于WCF服务项目并上载到IIS网站。然后,可以指示Web站点的App.config文件使用运行时数据库(再次在连接字符串中)到已部署的数据库。一切顺利! :)

© www.soinside.com 2019 - 2024. All rights reserved.