升级到 EF 4.1 后出现 System.NullReferenceException

发布于 2024-10-23 20:12:37 字数 1950 浏览 1 评论 0原文

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

I have an MVC3 app which was using EF CTP5. After upgrading to EF 4.1 I get NullReferenceException thrown from here:

   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)

I've got EF 4.1 bits from NuGet.

Database is initialized using custom initializer

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

The Exception is thrown from PopulateDatabase() method.

Any ideas?

UPDATE:

It seems that the problem stems from the instantiation of the second DatabaseContext to manually recreate the database. It must somehow interfere with the original context.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄情伤 2024-10-30 20:12:37

我已经使用 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);
    }
}

I have used Ladislav's decorator for closing opened connections but I had to modify it a bit. This was required (I believe) as I use sql authentication and have two connection strings (one with elevated permissions and one with only read/write).

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文