Reputation: 2738
It seems that the database is created at an unexpected time with EF 6.1 compared to 6.0.2. I need a way to check to see if the database is created. If it is not created, I created it and run some seeding code. I upgraded to 6.1 and this logic no longer works.
I created a simple project using 6.0.2 and then copied that project, updated EF and you can see the difference.
For both projects I use code first, create the migration and then run the solution. The first time it should see that the DB has not been created and create it and seed it. The issue is that the code that is used to check if the DB is created actually creates the DB when using 6.1. Because of this, the check always returns true and the seeding code is never ran.
Console app:
Program.cs
namespace SimpleEFTest2
{
class Program
{
static void Main(string[] args)
{
MyContext.InitializeDatabase();
}
}
}
TestEntity.cs:
namespace SimpleEFTest2
{
public class TestEntity
{
public int Id { get; set; }
public string SomeValue { get; set; }
}
}
MyContext.cs:
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace SimpleEFTest2
{
public class MyContext: DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
public ObjectContext ObjectContext
{
get
{
//With EF 6.0.2 this would throw an exception if the DB didn't exist.
//With EF 6.1.0 this creates the database, but doesn't seed the DB.
return ((IObjectContextAdapter)this).ObjectContext;
}
}
private static readonly Object syncObj = new Object();
public static bool InitializeDatabase()
{
lock (syncObj)
{
using (var temp = new MyContext())
{
ObjectContext oc = null;
try
{
oc = temp.ObjectContext;
}
catch (Exception ex)
{
//Ignore error
Console.WriteLine(ex);
}
//If oc != null && oc.DatabaseExists() return else create and seed DB
//With EF 6.1, oc.DatabaseExists() is always true because it was created in the function that gets the ObjectContext.
return true;
}
}
}
}
}
Configuration.cs
namespace SimpleEFTest2.Migrations
{
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<SimpleEFTest2.MyContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(SimpleEFTest2.MyContext myContext)
{
var entity = myContext.TestEntities.FirstOrDefault(i => i.SomeValue == "123");
if (entity == null)
{
entity = new TestEntity { SomeValue = "123" };
myContext.TestEntities.Add(entity);
}
myContext.SaveChanges();
}
}
}
Upvotes: 0
Views: 786
Reputation: 2738
I'm not sure why I didn't see this before...
DbContext.Database has a method Exists(). This will return the correct result without creating the database. I changed the code to use that and now 6.0.2 and 6.1.0 both work the same.
New MyContext.cs:
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using SimpleEFTest2.Migrations;
namespace SimpleEFTest2
{
public class MyContext: DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
public ObjectContext ObjectContext
{
get
{
//With EF 6.0.2 this would throw an exception if the DB didn't exist.
//With EF 6.1.0 this creates the database, but doesn't seed the DB.
return ((IObjectContextAdapter)this).ObjectContext;
}
}
private static readonly Object syncObj = new Object();
public static bool InitializeDatabase()
{
lock (syncObj)
{
using (var temp = new MyContext())
{
if (temp.Database.Exists()) return true;
var initializer = new MigrateDatabaseToLatestVersion<MyContext, Configuration>();
Database.SetInitializer(initializer);
try
{
temp.Database.Initialize(true);
return true;
}
catch (Exception ex)
{
//Handle Error in some way
return false;
}
}
}
}
}
}
Upvotes: 1