Postgres EF Migrations "3F000: No schema has been selected to create in" - postgresql

I am attempting to execute an initial database creation migration using entity framework core against a postgres database.
The problem I am having is that I wish to create the tables under a custom schema.
I have managed to create an initial migration with no problems but when I attempt to "update-database" the migration fails with the following error.
Npgsql.PostgresException (0x80004005): 3F000: no schema has been selected to create in
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<g__ReadMessageLong|0>d.MoveNext()
Having initial looked into the issue I assumed this was simply because the schema was not being set in the context.
To get around this I set added the following code to the DbContext
protected override void OnModelCreating(ModelBuilder builder)
{
//Set the default schema
builder.HasDefaultSchema("ConfigStore");
//Continue with the call./Migrate
base.OnModelCreating(builder);
}
I still get the same error when running update-database.
I checked the initial migration Up() method and can clearly see the following code:
migrationBuilder.EnsureSchema(name: "ConfigStore");
The migration creates the database but nothing else so I assume the problem here is that the schema is not being created after the database which is then subsequently causing the table creations to fail.
The question I have is how do I fix this?
Can I execute some custom sql AFTER the database has been created but before the tables? Is there something I can do to get EnsureSchema() to create the schema first?
Thanks in advance

Would you believe it. Hours and hours trying to figure it out and 10 minutes after posting on stack overflow I find the solution....
The problem was the initial connection string. I had defined the connection string as follows:
Server=127.0.0.1; port=5432; user id=XXXX; password=XXXX; database=Test; pooling=true; SearchPath=ConfigStore
The problem was the search path. Apparently EF Migrations creates the database perfectly with this connection string but then attempts to access the tables before creating the schema causing the error reported. Removing the search_path from the connection string resulted in the schema being created first, then the tables. Odd - but hey it works.

I have my custom schema kernel. The following search path helped me to resolve the issue
"Host=localhost;Database=test08;SearchPath=kernel,public;Username=postgres;Password=strongPa$$123;"

Related

Hibernate persisting incorrect values

I have some Hibernate code running against a Postgres 9.5 DB, which looks like roughly like below (anonymized) -
Integer myEntityId = myEntity.getId();
getCurrentSession().evict(myEntity);
myEntity.setId(null);
MyEntity clonedMyEntity = (MyEntity)getCurrentSession().merge(myEntity);
myEntity.setMyBooleanField(false);
getCurrentSession().save(myEntity);
I have an entity myEntity with a large number of fields. I want to create a duplicate of the record with only 1 field value changed. To achieve this, I evict the entity from session, set Primary Key to null, merge it back to session, set the field I want to change, and then save the entity to DB. However, this code (which was working correctly for some time), is not working now. It sees incorrect value for the boolean field I am trying to modify - as a result violating some database constraints. Please help me fix this or suggest a better way to achieve what I am trying.
The error was happening not on adding this record but on add of another record to an audit table, triggered by the addition of this record. A coworker suggested me to use Eclipse Breakpoint view and use the add breakpoint option there and select the ConstraintViolationException class - this helped me to see the error for which trigger was failing and why and accordingly modify the data to suit the database constraint.

EF7 "Invalid Object Name 'xyz'" when manually scaffolding existing database

I've published a DB using an SqlDatabase Project.
I've manually created POCO classes, as well as a Db context to match the published database.
Whenever I try to execute an EF statement, valid SQL Query is generated, but I receive the error
An exception occurred in the database while iterating the results of a query.
System.Data.SqlClient.SqlException (0x80131904): Invalid object name '[xyz]'
The properties on the EF class match exactly type/nullable/name/etc in the database. The query generated, when run manually works fine.
Any help appreciated.

EF code-first migration: SqlCeException altering NTEXT column

My application uses Entity Framework 5.0 code-first on top of a Sql CE database. Until now, we have used Automatic Migrations to manage entity mapping changes. However, I now have a change for which I need to create a custom migration to ensure no data is lost during the update. I made my changes to the entities, and used the Add-Migration command which generated Up() and Down() methods for me. I customized the Up() method to insert my custom sql to preserve the data, and tested my application.
When I run the application, I received the error:
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
Ok, I don't understand this because all of my changes are detailed in the Up() method that got executed.
So I turn Automatic Migrations back on just to see what happens. Now I receive this error:
"Cannot alter column of type NTEXT or IMAGE [ Column Name = LastName ]"
This error comes from a table/entity that hasn't even been touched with my changes. The existing database has this string mapped to nvarchar(4000). If I examine the DB after I receive this exception, I observe that the columns have been changed to ntext. What is EF doing? Why is it touching tables that haven't been changed? How can I get more information on what is going on here?
Update:
As a workaround, I attempted to mark each and every string type in my entities with a data annotation as such:
[Column(TypeName = "ntext")]
public virtual string LastName
{
get;
set;
}
Now all of my strings are using ntext in the database. This leads to further exceptions when queries are performed:
The ntext and image data types cannot be used in WHERE, HAVING, GROUP BY, ON, or IN clauses, except when these data types are used with the LIKE or IS NULL predicates.
So, to summarize:
Turning off automatic migrations causes EF to detect phantom changes and throw exceptions
Turning on automatic migration in conjunction with a custom migration causes all existing strings to be mapped to ntext
strings mapped to ntext cannot be queried, effectively making them useless in my application
For me, a modification of an Up method worked out.
SerialNumber = c.String(maxLength: 99)
was applied instead of
SerialNumber = c.String()
i had the same issue and i fixed by editing the table column data type manually by opening SQl Server Compact/SQlite Toolbox explorer windows, and then expend the database name, then expend the table you want to edit and right click the column you want to edit, and click drop script, then run the scrip and the column will be dropped from the table, then right click the table and click add column and from here you can choose what data type you want and add the new column that way. I hope this helps some one.

Entity Framework 6 Code First Migration's ContextKey

Now i'm using EF6 Alpha, and when using migration, it will add a new migration log into the __MigrationHistory table.
In EF6, The __MigrationHistory table has a new column called "ContextKey". After testing, I found there are two default "ContextKey" value:
The full name of DbContext's derived class.This happens when i run the code:
Database.CreateIfNotExists();
The full name of DbMigrationsConfiguration's derived class. This happens when i run the code:
public ArticleDbContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ArticleDbContext, ArticleConfiguration>());
}
The first time i run the application, "Database.CreateIfNotExists();" create a new database for me, also all tables that map to the models defined in ArticleDbContext, and then add a __MigrationHistory row which ContextKey's value is "Module.Article.Model.ArticleDbContext".
And then "Database.SetInitializer(new MigrateDatabaseToLatestVersion());" will be runned, this code will generate a new ContextKey "PowerEasy.Module.Article.Migrations.ArticleConfiguration". Migration query the __MigrationHistory table with this ContextKey and find out there's no data. So again it will create all tables that map to the models defined in ArticleDbContext, but the tables are already exist in the database, so an exception will be throwed, and tell me "the table XXX is already existed".
How can i solve this?
You should not mix Migrations and the Database.CreateIfNotExists method (or any of the initializers built on top of it). Migrations will take care of creating the database if it does not already exist.
As an alternative to the Migrations initializer, you can also apply migrations using the DbMigrator.Update method. This is useful if you want to create/update the database before it would otherwise be triggered by the initializer.

EF Code First: Migrating Database Initialized on Different Code Versions

I am using Entity Framework 5 RC, code first. I am struggling with migrating databases that were created on different versions of code. For example, Database A was created when table FooBar didn't exist. Database B was created after table FooBar was added to my model.
I have a migration written that adds the FooBar table. Is it my responsibility to check in the FooBar migration that the table doesn't exist before calling CreateTable? It seems that is the case since Database B doesn't have an entry for the FooBar migration and will attempt to run it.
At first the MigrationHistory table seemed like it would save me from adding these checks but since new databases won't have entries for migrations added before the database was created, I still need to do the checks myself. Is that the right way to go about it or am I missing something?
To get around an issue I had with adding Stored Procedures, I wrote a TSQL script to create a new table "_PreviousMigrationHistory" - which receives new entries from the "_MigrationHistory" table after my stored procedure scripts have run...
I did add a new column to both tables ( "VersionId", of INT - IDENTITY(1,1) ) which is what I use for comparison within my code.
This way you have the un-updated migration patterns available to you (__PreviousMigrationHistory), even after Code First Migrations have occurred.
Would this help?
**EDIT - sorry, I miss read the question. - Although I would think that new instances of the database would still go through the migration steps, which in turn should add the entries to the __MigrationHistory table?