数据库在EF 6.0.2和6.1之间创建不同

时间:2014-03-31 18:49:09

标签: entity-framework

似乎数据库是在意外的时间使用EF 6.1与6.0.2相比创建的。我需要一种方法来检查数据库是否已创建。如果没有创建,我创建它并运行一些种子代码。我升级到6.1,这个逻辑不再有效。

我使用6.0.2创建了一个简单的项目,然后复制了该项目,更新了EF,你可以看到差异。

对于这两个项目,我首先使用代码,创建迁移然后运行解决方案。第一次它应该看到DB尚未创建并创建它并播种它。问题是用于检查是否创建了DB的代码实际上在使用6.1时创建了DB。因此,检查始终返回true,并且永远不会运行种子代码。

控制台应用:

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

1 个答案:

答案 0 :(得分:1)

我不确定为什么我之前没有看到这个......

DbContext.Database有一个方法Exists()。这将返回正确的结果而不创建数据库。我更改了代码以使用它,现在6.0.2和6.1.0都运行相同。

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