6

I am attempting to set up my application to use Entity Framework with PostgreSQL, but I have run up against a problem. I have added Npqsql via nuget, and added the following provider factory to 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>

With the connection string:

    <add name="MyDb" providerName="Npgsql" 
connectionString="Server=localhost;Port=5432;Database=withoomph;User ID=postgres;Password=******;enlist=true" />

It seems to connect to the DB fine, but when I try and do any sort of action on the DB I get the following exception:

FATAL: 3D000: database "withoomph" does not exist

I am setting the database intitializer correctly when the db is set up like so:

static MyDB()
{
    Database.SetInitializer<MyDB>(new CreateDatabaseIfNotExists<MyDB>());
}

So it should just simply create db when I try and do anything with my DbContext right? I don't get it, been pulling my hair out all morning!

3 Answers 3

9

Unfortunately, Npgsql does not have (as of now) automatic schema creation code-first.

You can create your database first, and then connect to it.

Update (2016): Npgsql 3 now implements database creation code-first. Make sure you configure the correct connection factory to use NpgsqlConnections, either via code or via the XML settings, and use an appropriate Connection String.

Sign up to request clarification or add additional context in comments.

8 Comments

At last after god knows how much trawling the internet i have finally been given the precise reason why this is happening! Thank you, at least now I know it's either DB-first with pgsql, or code first with something else :-)
Adding a comment nearly 2 years after my answer... New Npgsql 2.2.0 version includes support for migrations and codefirst with EF6
May i ask how? I used nuget to install Npgswl.Entityframework (v 2.2.5). This installed also EF6 and npqsql 2.2.5 . I got an exception that dbo.xyz is not available. using (DataAccessContext db = new DataAccessContext(dbConnection)) { IObjectContextAdapter adapter = (IObjectContextAdapter)db; string script = adapter.ObjectContext.CreateDatabaseScript(); -> Excepton :"CreateDatabaseScript is not supported by the provider."
I'm a little confused. are you saying once the database exists, EF actually does create tables from entities in code first? Because I couldnt get npgsql to create tables either.
With current EntityFramework (6.1.3) and EntityFramework6.Npgsql (3.0.5) from NuGet, and with proper user permission (in my case a classical super user), I get the full database creation from an empty postgresql setup. It was not possible in 2013, when this answer was first added.
|
4

Not surprisingly, since your database withoomph is not created yet, you should not able to use connection string where Database=withoomph; is mentioned.

What you can do is to either create this database manually using createdb or psql, or change your connection string temporarily to use Database=postgres; instead.

This should work because on all recent PostgreSQL versions database postgres is guaranteed to exist after vanilla install and should be used just for this purpose - to get initial authenticated connection to create another database and issue CREATE DATABASE withoomph; within your application.

However, after your new database is created, you should immediately disconnect from postgres, connect to new withoomph and continue normally.

1 Comment

Ok, I will try it out. It has thrown me because this is different behavior than every other type of SQL db I have attempted to use EF with, there's not much information about on how to do this as well. I shall report back.
2

In addition to mvp's answer, here's a code snippet I used to create the database. You need to run it before initializing EF. So, the trick is to switch the database name temporarily to 'postgres', which is guaranteed to exists after a vanilla install.

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();
    }
}

2 Comments

Hey, I'm having the same issue. Was wondering where you get this method triggered? On the initializer? I followed the instruction where I changed the web.config to "postgres", but now it's checking postgres database and does not trigger my initializer. Should I be putting this on the global.asax.cs? Thank you!
I usually have a separate console in which I perform such opertions. You could put it in the global.asax in the app start, but then you should check if the database exists first, otherwise it will recreate your database every time you start the application :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.