C# 无法首先使用Npgsql和实体框架代码在PostreSQL中创建数据库

C# 无法首先使用Npgsql和实体框架代码在PostreSQL中创建数据库,c#,entity-framework,postgresql,npgsql,C#,Entity Framework,Postgresql,Npgsql,我试图将我的应用程序设置为使用实体框架和PostgreSQL,但遇到了一个问题。我通过nuget添加了Npqsql,并将以下提供程序工厂添加到web.config: <system.data> <DbProviderFactories> <add name="Npgsql Data Provider" invariant="Npgsql" description=".Net Framework

我试图将我的应用程序设置为使用实体框架和PostgreSQL,但遇到了一个问题。我通过nuget添加了
Npqsql
,并将以下提供程序工厂添加到
web.config

<system.data>
    <DbProviderFactories>
        <add name="Npgsql Data Provider" 
           invariant="Npgsql" 
           description=".Net Framework Data Provider for Postgresql Server" 
           type="Npgsql.NpgsqlFactory, Npgsql, 
                 Version=2.0.12.0, Culture=neutral, 
                 PublicKeyToken=5d8b90d52f46fda7" />
    </DbProviderFactories>
  </system.data>

所以当我尝试使用我的
DbContext
做任何事情时,它应该只创建db,对吗?我不明白,整个上午都在拉扯我的头发

毫不奇怪,因为您的数据库
withoomph
尚未创建,所以您应该无法使用连接字符串,其中
数据库=withoomph

您可以使用
createdb
psql
手动创建此数据库,或者临时更改连接字符串以使用
database=postgres取而代之

这应该是可行的,因为在所有最新的PostgreSQL版本上,数据库
postgres
保证在普通安装后存在,并且应该仅用于此目的-获得初始身份验证连接以创建另一个数据库,并发出
create database with oomph在应用程序中


但是,在创建新数据库后,您应该立即断开与postgres的连接,使用OOMPH连接到new
,然后继续正常运行。

不幸的是,Npgsql没有(目前为止)自动模式创建代码

您可以先创建数据库,然后连接到它


更新(2016):Npgsql 3现在首先实现数据库创建代码。确保通过代码或XML设置将正确的连接工厂配置为使用
NpgsqlConnection
s,并使用适当的连接工厂。

除了mvp的答案之外,下面是我用来创建数据库的代码片段。您需要在初始化EF之前运行它。 因此,诀窍是将数据库名称临时切换为“postgres”,这保证在普通安装后存在

public void CreateDatabase(string connectionString)
{
    var builder = new NpgsqlConnectionStringBuilder(connectionString);
    var databaseName = builder.Database; // REMEMBER ORIGINAL DB NAME
    builder.Database = "postgres"; // TEMPORARILY USE POSTGRES DATABASE

    // Create connection to database server
    using (var connection = new NpgsqlConnection(builder.ConnectionString))
    {
        connection.Open();

        // Create database
        var createCommand = connection.CreateCommand();
        createCommand.CommandText = string.Format(@"CREATE DATABASE ""{0}"" ENCODING = 'UTF8'", databaseName);
        createCommand.ExecuteNonQuery();

        connection.Close();
    }
}

好的,我试试看。它引发了我的兴趣,因为这与我尝试使用EF的所有其他类型的SQL db的行为不同,关于如何做到这一点,也没有太多的信息。我会向你汇报的。在上帝知道我在互联网上被拖网了多少次之后,我终于得到了发生这种事情的确切原因!谢谢你,至少现在我知道它要么是DB优先使用pgsql,要么是代码优先使用其他东西:-)在我的回答将近2年后添加一条评论。。。新的Npgsql 2.2.0版本包括对迁移的支持,以及对EF6的codefirst的支持。我可以问一下,怎么做?我使用nuget安装Npgswl.Entityframework(v2.2.5)。这也安装了EF6和npqsql 2.2.5。我得到一个异常,dbo.xyz不可用。使用(DataAccessContext db=new DataAccessContext(dbConnection)){IObjectContextAdapter=(IObjectContextAdapter)db;字符串脚本=adapter.ObjectContext.CreateDatabaseScript();->Excepton:“提供程序不支持CreateDatabaseScript。”我有点困惑。你是说一旦数据库存在,EF实际上会首先从代码中的实体创建表吗?因为我也不能让npgsql创建表。使用NuGet当前的EntityFramework(6.1.3)和EntityFramework6.npgsql(3.0.5),并具有适当的用户权限(在我的例子中是一个经典的超级用户),我从一个空的postgresql设置中获得完整的数据库创建。这在2013年第一次添加此答案时是不可能的。嘿,我也有同样的问题。想知道在初始化器上从何处触发此方法?我按照指示将web.config更改为“postgres”,但现在它正在检查postgres数据库,并且不会触发我的初始值设定项。我应该将其放在global.asax.cs上吗?谢谢!我通常有一个单独的控制台,在其中执行此类操作。您可以将其放在应用程序启动中的global.asax中,但您应该首先检查数据库是否存在,否则它将重新创建您的d每次启动应用程序时使用Database:)
static MyDB()
{
    Database.SetInitializer<MyDB>(new CreateDatabaseIfNotExists<MyDB>());
}
public void CreateDatabase(string connectionString)
{
    var builder = new NpgsqlConnectionStringBuilder(connectionString);
    var databaseName = builder.Database; // REMEMBER ORIGINAL DB NAME
    builder.Database = "postgres"; // TEMPORARILY USE POSTGRES DATABASE

    // Create connection to database server
    using (var connection = new NpgsqlConnection(builder.ConnectionString))
    {
        connection.Open();

        // Create database
        var createCommand = connection.CreateCommand();
        createCommand.CommandText = string.Format(@"CREATE DATABASE ""{0}"" ENCODING = 'UTF8'", databaseName);
        createCommand.ExecuteNonQuery();

        connection.Close();
    }
}