EF code first - Model compatibility cannot be checked because the database does not contain model metadata - entity-framework

I have enabled automatic migrations. Then, I deleted my whole db. Next, i executed Update-database from command console, and it recreated my db. Then, I started my application only to see this error:
Model compatibility cannot be checked because the database does not
contain model metadata. Model compatibility can only be checked for
databases created using Code First or Code First Migrations.
So what exactly is that metadata, and how can I point entity framework to it?
PS. My database contains table named MigrationsHistory.

Here is a detailed description of the possible ways to resolve this which I wrote a while ago...
(not exactly what you're experiencing, hence not a duplicate per se, but with different scenarios in mind)
https://stackoverflow.com/a/10255051/417747
To summarize...
What works for me is to use Update-Database -Script
That creates a script with a 'migration difference', which you can
manually apply as an SQL script on the target server database (and you
should get the right migration table rows inserted etc.).
If that still doesn't work - you can still do two things...
a) remove the migration table (target - under system tables) - as per
http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-automatic-migrations-walkthrough.aspx
comments in there - that should fail back to previous behavior and if
you're certain that your Db-s are the same - it's just going to 'trust
you',
b) as a last resort I used - make a Update-Database -Script of the
full schema (e.g. by initializing an empty db which should force a
'full script'), find the INSERT INTO [__MigrationHistory] records,
just run those, insert them into the database, and make sure that your
databases - and code match,
that should make things run in sync again.
if it helps

Detach your local Database say example 'database1.mdf' from visual studio 'server explorer' and then open SQL server management studio right click on Databases > Attach and then browse the same 'database1.mdf' file .If you doesn't have access then copy&past both the mdf and ldf files into c drive and do attach.
Then open new query window on sql server then do copy your identity tables as like below query.
*'select * into [__MigrationHistory] from Database1.dbo.__MigrationHistory '*

Add this to your context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}

I use Entity Framework 6 , SQL 2008 R2 , VS 2013.
To solve this problem only use the following procedure :
1) delete existing db ( existing database that created with EF model{code first})
2) Run APP again.
Fore example query code (in Layout):
this code create db if my model is change and search username in user table.
<body>
#{
// Delete && Create ...
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DBContext>());
var db = new DBContext();
var SearchingUser = db.Users.Where(c => c.UserName == "qwertyui");
if (SearchingUser.Count() == 0) {
var User = new Users { UserName = "qwertyui",Password = "12345678" };
db.Users.Add(User);
db.SaveChanges();
}
}
#RenderSection("scripts", required: false)
#RenderBody()
</body>

Package Manager Console > Enable-Migrations -EnableAutomaticMigrations
Configure Migrations/Configuration.cs
Package Manager Console > Update-Database

Related

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

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;"

Avoiding Vapor migrations on a new database

I've created migration for adding a field to the Postgres table, it works as expected on the existing database. But when I want to run the same vapor server with a new database it crashes on the migration with the "field already exists" message, which is, of course, understandable. But how to maintain the server code so it could work both with existing and new databases?
Fatal error: Error raised at top level: PostgreSQL Error: column "the_coloumn" of relation "User" already exists
- id: PostgreSQLError.server.error.check_for_column_name_collision
: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1100.8.280/swift/stdlib/public/core/ErrorType.swift, line 200
Assuming you have deployed the application and have multiple installations then you will need to preserve the two versions of the table. If you haven't then you could always delete the second migration if it does nothing more than add the field. As you have discovered, the field gets created in the first migration on a new installation.
However, if you have to have both then you will need to replace your use of AddProperties in the original migration that builds the table with an explicit list of the fields, less the one you are adding in the second migration. Examples of individual field creations are:
extension User:Migration
{
static func prepare(on connection:MySQLConnection) -> Future<Void>
{
return Database.create(self, on:connection)
{
builder in
builder.field(for:\.id, isIdentifier:true)
builder.field(for:\.surname, type:.varchar(30, characterSet:nil, collate:nil))
builder.field(for:\.firstName, type:.varchar(30, characterSet:nil, collate:nil))
}
}
}
This will build the table as you had it before when you created the table in the original database. Then your second migration will work as before. See https://docs.vapor.codes/3.0/fluent/migrations/ for more information.

Dis-Advantages of using EF 6.x.x Code First without Migration

I am fed up of using/running Add-Migration and Update-Database because lot of time we forget to run migrations on production database. So, we decided to delete all migrations from database table as well all migration classes. So, what if my __MigrationHistory table remains always empty and no migration classes. What is the main disadvantage?
No this is a bad idea, the [__MigrationHistory] is used to compare your current used conceptual model with the storage model.
1) Case: DbMigrationsConfiguration automatic:
[__MigrationHistory] keeps track for the last migration.
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
as shown in the image above, the migrationId is the migration identifier and the model column is a base64 representation of the binary stream of your current conceptual model.
2) Case: DbMigrationsConfiguration non-automatic:
[__MigrationHistory] keeps track of every migration.
this.AutomaticMigrationsEnabled = false;
this.AutomaticMigrationDataLossAllowed = false;
Each migration level obtain a migrationId identifier which is used for migration level up/level/down.
Best practice: If you want to use the automatic migration just regenerate the migration and shipped to the custmer.
If you are using non-automatic migration.
1) If the customer need the data then just tranform the data with SQL to the new db schema
2) If the customer does not need the data then just drop the database an create it again with initialCreate.
If you want to create the database without any migrationHistory info:
// Create the database. You can generate it from SMO "Script database as" and if the database exist then just ignore the creation
// Do not forget to remove the [__MigrationHistory] rows.
DbContext.Database.ExecuteSqlCommand("SQLCreateDbScript.sql");
Database.SetInitializer<MyDbContext>(null);
using (var dbContext = new MyDbContext())
{
// Create DbContext and it works!
dbContext.Users.Add(new User());
dbContext.SaveChanges();
}
I hope this will help you to solve the problem!
And if you want something really with less Db-Schema then use NoSql with EF.
In Core version still not done but with the old version EF6 it is possible todo that (NoSql Db) with: http://www.brightstardb.com or use the Polyglot appoarch from microsoft https://msdn.microsoft.com/en-us/library/dn271399.aspx

How to use SQL Server Views with EF Code First Migrations

I've reverse engineered a small database that contains a number of tables and views into EF 5 code first.
When I do this, I get a set of models and mapping classes for each of my tables and these work well when I try to query the database using the generated DbContext.
It also generates POCO classes for each of my views, but when I run Enable-Migrations and Add-Migration using the Package Manager Console, the migration does not re-create the SQL Server views.
I have tried updating the migration manually to create the views using custom SQL like so:
Sql("CREATE VIEW [dbo].[viewUsersDeactivated] "
+ "AS "
+ "SELECT ... ");
This works fine when I run Update-Database, but the SQL script that is output from the Update-Database -Script command does not seem to be valid, resulting in the following error:
'CREATE VIEW' must be the only statement in the batch.
Inserting Sql("GO"); between each of the custom SQL statements works for the script generation, but then I can no longer update using Update-Database, and I can't find a way that works for both.
So my question boils down to: How can I include SQL Server views in a code first migration script such that I can create a database both using Update-Database and via production scripts generated using Update-Database -Script?
Thanks!
Not entirely sure this is best practice, and someone else might have a better solution, but I got around this by wrapping the entire view creation script in an Execute, thus:
var sql = "CREATE VIEW [dbo].[TheViewName] AS ......."
sql = sql.Replace("'", "''"); // sanitize the sql string
sql = string.Format("EXECUTE sp_executesql N'{0}'", sql);
Sql(sql);

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?