升级到 EF 4.1 后的 System.NullReferenceException

Posted

技术标签:

【中文标题】升级到 EF 4.1 后的 System.NullReferenceException【英文标题】:System.NullReferenceException after upgrade to EF 4.1 【发布时间】:2011-03-19 22:32:26 【问题描述】:

我有一个使用 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 以手动重新创建数据库。它必须以某种方式干扰原始上下文。

【问题讨论】:

如何初始化数据库? @Jakub,我在 Exception 的堆栈跟踪中没有看到 NullReferenceException...此外,您能否使用符合 sscce 的示例复制该错误? @Ladislav - 谢谢,我会尝试更改初始化程序,看看会发生什么。 顺便说一句。为什么要使用第二个上下文? 我认为您已经找到了自己的解决方案。移动它以回答并接受它。如果我的装饰师帮助您,只需支持我的链接答案。我通常不喜欢在没有任何附加信息作为答案的情况下重新发布指向其他问题的简单链接。 【参考方案1】:

我使用了Ladislav's decorator for closing opened connections,但我不得不稍微修改一下。这是必需的(我相信),因为我使用 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);
    

【讨论】:

以上是关于升级到 EF 4.1 后的 System.NullReferenceException的主要内容,如果未能解决你的问题,请参考以下文章

EF 4.1 RC Code First - 映射到现有数据库并指定外键名称

NHibernate 与 EF 4.1+ [关闭]

将 EF 4 EDMX 升级到 EF 6

EF 4.1 中的多个实体

EF 4.1 Mapper 类的使用

EF 4.1 模型中的图像数据类型优先