EF Code First Existing database - entity-framework

Using EF 4.1 Code first I wanted to stop EF creating database from Models. As I understand if you pass Connectionstring name it will use existing database from that connection string. However if the database does not exists then it will create database will all the tables form the model.
<connectionStrings>
<add name="DiaryContext" connectionString="Data Source=.;Initial Catalog=Diary;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
public MyDiaryContext() :
base("name=DiaryContext")
{
this.Configuration.LazyLoadingEnabled = true;
this.Configuration.ProxyCreationEnabled = false;
}
In the above example its behaving as follows:
(1) if database does not exists then it will create the database with all the tables etc.
(2) if the database exists and it has no tables then it will not create new tables
(3) if I add new model the EF code then it will not create the new table in the database.
I am happy with 2 and 3 but in case of (1) if database does not exists then I wanted it to throw the exception instead of creating the db and tables.
In my case the database is being managed by DBA and I dont have total control over this.
Does anyone have any idea how to achive this?
Many thanks,

When you use EF Code first you need to set a DB Initializer I for example do this in the constructor of my DataContext
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<WebContext>());
There are a few default implmentations like DropCreateDatabaseIfModelChanges and DropCreateDatabaseAlways you can use. If however you don't wont any DB or tables generate just make sure that no Initializer is being set or inherited from and you can use the model against an existing db. Good article by scot gu

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

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

Entitfy Framework DbContext and xxxEntities?

I have a SQL server db ( with tables etc) and ive installed ef6 in order to use async stuff ( p.s. im new to ef).
So I added this :
played with the wizard and created a valid edmx files.
My db name is DUMP so it added Dumpentities suffix :'
so now i can do :
de = new DumpEntities1();
var data=de.AgeGroups.ToList()
But why don't I Have DbContext ? like I see in many places ?
Is xxxEntityes is a replacement for DbContext ?
cause it seems i can do all actions with xxEntites ...
edit
Ive searched "dbcontext" in my solution and apprently i do have it :
So what is going on here?
does using xxxEntiyies is the new way ?( and not doing xxxContext = new xxxContext()...even if I wanted - I dont have it...)
You should not use DbContext directly (that will not make sense) in Entity Framework. Instead you use your own custom context - class inherited from DbContext which holds sets specific to your application. When you use database first approach this custom entity class will be generated based on edmx file data, which in his turn will be generated based on database schema.
Regarding to naming... its not obvious but custom context which will be generated, will have same name as connection string name when you are creating edmx file:
Actually this will be default name for Entity Container of your conceptual entity model. If you will open edmx file in designer and take a look on its properties, you will see:
If you will change this name, context will be re-generated with name you have provided.

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.

Model is not reading from my Database (Entitity Framework)

I created simple MVC application with a database.
First I created a database, initialized the database, then I created a model from the database and the application worked..
Then I decide to load database with totaly different values (but the definitons of tables/fields stayed the same)..
After reloading the database my application does not shows any data from my DB. Using debugger I saw that my application cannot get any data from the table.
Worse - I noticed that additional to my database TestDB, the database explorer is showing TestDB.mdf1 database, with the same definitions as testDB.mdf but table is empty...
Here is the code:
public ActionResult ShowQuestions()
{
TestDBEntities _db = new TestDBEntities(); // this is the database
ObjectSet<question> all_quest = _db.questions ; // this is the table
foreach (var x in all_quest)
{
..... // this part was never executed
}
return View(q_list);
}
Any ideas what I am doing wrong?
1- check the connection string in your MVC application (web.config). This will tell you which database is being used. Then go to this database and check if you have data in your tables.
If it's the wrong database, just amend the connection string.
2- If it's the correct database, but without data, just add data.
It may have been recreated by your ORM (who knows?).
3- What is the error you are getting? Or are you getting any error?