1

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

在我的 ASP.NET MVC 3 项目中,我DbContext在 Global.asax ( 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 进行一次 CRUD 操作。

StackTrace 用于New transaction is not allowed because there are other threads running in the session

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

StackTrace 用于Object reference not set to an instance of an object.

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 
4

2 回答 2

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);
        }
    }
}
于 2012-07-30T18:38:58.923 回答
1

注册MyContext看起来没问题。是否有可能其他一些接受 a 的服务MyContext被注册为单例并跨线程共享?

于 2012-07-16T14:03:18.983 回答