3

我有一个使用 EF CTP5 的 MVC3 应用程序。升级到 EF 4.1 后,我NullReferenceException从这里被抛出:

   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
   at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)

我从 NuGet 获得了 EF 4.1 位。

使用自定义初始化程序初始化数据库

    public class RecreateDatabaseInitializer : IDatabaseInitializer<DatabaseContext>
    {
        public void InitializeDatabase(DatabaseContext context)
        {
            if (ConfigurationManager.ConnectionStrings["DatabaseContextSA"] == null)
            {
                EventLog.WriteEntry("RecreateDatabaseInitializer", "Connection string 'DatabaseContextSA' doesn't exist in config file.", EventLogEntryType.Warning);
                return;
            }

            using (var ctx = new DatabaseContext("DatabaseContextSA"))
            {
                if (ctx.Database.Exists())
                    DropDatabase(ctx);

                CreateDatabase(ctx);
                InitializeDatabaseObjects(ctx);
                ctx.SaveChanges();
            }

            PopulateDatabase(context);
            context.SaveChanges();
        }
    }

异常是从PopulateDatabase()方法中抛出的。

有任何想法吗?

更新:

似乎问题源于实例化第二个 DatabaseContext 以手动重新创建数据库。它必须以某种方式干扰原始上下文。

4

1 回答 1

1

我使用了 Ladislav 的装饰器来关闭打开的连接,但我不得不对其进行一些修改。这是必需的(我相信),因为我使用 sql 身份验证并且有两个连接字符串(一个具有提升的权限,一个只有读/写)。

public class ForceDeleteInitializer : IDatabaseInitializer<DatabaseContext>
{
    private readonly IDatabaseInitializer<DatabaseContext> InnerInitializer;

    public ForceDeleteInitializer(IDatabaseInitializer<DatabaseContext> innerInitializer)
    {
        this.InnerInitializer = innerInitializer;
    }

    public void InitializeDatabase(DatabaseContext context)
    {
        using (var ctx = new DatabaseContext("DatabaseContextSA"))
        {
            Database.SetInitializer<DatabaseContext>(null);
            ctx.Database.ExecuteSqlCommand("ALTER DATABASE " + ctx.Database.Connection.Database + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
        }

        this.InnerInitializer.InitializeDatabase(context);

        Database.SetInitializer<DatabaseContext>(this);
    }
}
于 2011-03-20T17:11:15.490 回答