实体框架+ Autofac - 保存时的随机错误

时间:2012-07-16 13:48:27

标签: entity-framework autofac dbcontext object-lifetime

使用autofac作为我的IoC框架 我希望能够在我的应用程序的启动中设置我的DbContext实例。

在我的ASP.NET MVC 3项目中,我在Global.asax(DbContext)中注册PerLifetimeScope实例。但是当我一次在多个浏览器(或多个标签页)上启动我的网站时,有时当我尝试将更改保存回数据库时,我得到Object reference not set to an instance of an object.New transaction is not allowed because there are other threads running in the session。我也明白了 有时当我想从数据库中读取数据时,ExecuteReader requires an open and available Connection. The connection's current state: Broken.

错误似乎随机弹出,我怀疑它与我的上下文的生命周期范围有关。这是我的DbContext的覆盖SaveChange方法。

public class MyContext : DbContext
{ 
    public override int SaveChanges()
    {
        var result = base.SaveChanges(); // Exception here
    }
}

以下是我如何注册我的上下文:

builder.Register(c => new MyContext("SomeConnectionString"))
                 .InstancePerLifetimeScope(); 

如果我在浏览器中只有一个打开的网站标签,一切正常 另外,值得一提的是,通过使用Ajax调用控制器方法,我的网站每5-10秒就有一次db操作。

New transaction is not allowed because there are other threads running in the session的StackTrace:

at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs

Object reference not set to an instance of an object.的StackTrace:

at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
at System.Data.Objects.ObjectStateManager.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)
at System.Data.Entity.Internal.InternalContext.GetStateEntries()
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()
at System.Data.Entity.DbContext.GetValidationErrors()
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs   at 

2 个答案:

答案 0 :(得分:1)

MyContext的注册看起来不错。是否有可能将MyContext的其他服务注册为单例并在线程间共享?

答案 1 :(得分:1)

我遇到了同样的问题,在使用Autofac解析DbContext时,与DbContext相关的零星错误。

{System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.
etc.

{System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
etc.

我在代码中找到了类似下面的类。依赖性解析发生在单例内部的静态方法中。正在解析的对象依赖于DbContext。在我找到重组这个类的方法后,我没有任何其他问题,因此它不再是单例。

也许你有类似的情况?另一件事可能是制作你的DbContext InstancePerHttpRequest。这有助于确定这是否是问题。

public class Singleton
{
    private static Singleton _instance = new Singleton();

    private Singleton()
    {

    }

    public static void DoSomething<TSource>(TSource source) where TSource : ISource
    {
        var items = DependencyResolver.Current.Resolve<IEnumerable<IDbContextConsumer<TSource>>>();
        foreach (var item in items)
        {
            item.Execute(source);
        }
    }
}