EF MVC连接';s的当前状态为打开,或者在发送多个请求时下划线提供程序无法打开

本文关键字:请求 程序 下划线 连接 MVC EF 状态 或者 | 更新日期: 2023-09-27 18:24:05

我们有一个MVC 4中的web应用程序,使用Entity Framework 6.1,并使用unity作为DI框架。当我们向一个页面发送许多请求时,我们得到了以下错误:"连接的当前状态是打开的"或有时"下划线提供程序无法打开"我认为这应该是由多线程使用UnitOfWork或DbContex的一个实例引起的,但我们检查了一下,没有发现任何错误,这是我们的代码

///////////////////////////////////////////////////////////////数据库工厂

public class DatabaseFactory : Disposable, IDatabaseFactory
{
    private MyDbContext dataContext;
    public MyDbContext Get()
    {
    var context=     dataContext ?? (dataContext = new MyDbContext());
        return context;
    }
    protected override void DisposeCore()
    {
        var dataContextAdapter = dataContext as IObjectContextAdapter;
        if (dataContextAdapter != null && dataContextAdapter.ObjectContext.Connection.State == ConnectionState.Open)
            dataContextAdapter.ObjectContext.Connection.Close();
        if (dataContext != null)
            dataContext.Dispose();
        }
}

///////////////////////////////////////////////////////////////单位工作

public class UnitOfWork :Disposable, IUnitOfWork
{
    private readonly IDatabaseFactory databaseFactory;
    private MyDbContext dataContext;
    private LogContext logContext;
    public UnitOfWork(IDatabaseFactory databaseFactory)
    {
        this.databaseFactory = databaseFactory;
    }
    protected override void DisposeCore()
    {
        var dataContextAdapter = dataContext as IObjectContextAdapter;
        if (dataContextAdapter != null && dataContextAdapter.ObjectContext.Connection.State==ConnectionState.Open)
            dataContextAdapter.ObjectContext.Connection.Close();
         if (dataContext != null)
            dataContext.Dispose();
        if (databaseFactory != null)
            databaseFactory.Dispose();
    }
    protected MyDbContext DataContext
    {
        get { return  (dataContext = databaseFactory.Get()); }
    }
    public bool Commit()
    {
        try
        {
            DataContext.SaveChanges();
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

///////////////////////////////////////////////////////////////存储库库

    public abstract class RepositoryBase<T> : Disposable where T : class
    {
        private MyDbContext dataContext;
        private readonly IDbSet<T> dbset;
        protected RepositoryBase(IDatabaseFactory databaseFactory)
        {
            DatabaseFactory = databaseFactory;
            dbset = DataContext.Set<T>();
        }
        protected override void DisposeCore()
        {
            var dataContextAdapter = dataContext as IObjectContextAdapter;
            if (dataContextAdapter != null && dataContextAdapter.ObjectContext.Connection.State == ConnectionState.Open)
                dataContextAdapter.ObjectContext.Connection.Close();
            if (dataContext != null)
                dataContext.Dispose();
        }
        protected IDatabaseFactory DatabaseFactory
        {
            get;
            private set;
        }
        protected MyDbContext DataContext
        {
            get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
        }
        public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
        {
            return dbset.Where(where).ToList();
        }
    }

///////////////////////////////////////////////////////////////UnityRegister类型

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<IDatabaseFactory, DatabaseFactory>(new HttpContextLifetimeManager<IDatabaseFactory>())
            .RegisterType<IUnitOfWork, UnitOfWork>(new HttpContextLifetimeManager<IUnitOfWork>())
            .RegisterType<IMyDbContext, MyDbContext>(new HttpContextLifetimeManager<IMyDbContext>())
           .RegisterType(typeof(IRepository<>), typeof(RepositoryBase<>))
            //Orders
            .RegisterType<IOrdersRepository, OrdersRespository>(new HttpContextLifetimeManager<IOrdersRepository>())
            .RegisterType<IOrdersService, OrdersService>(new HttpContextLifetimeManager<IOrdersService>())
            //Orders 
            ....
  }

任何建议和建议都将不胜感激

EF MVC连接';s的当前状态为打开,或者在发送多个请求时下划线提供程序无法打开

在我看来,正是这行代码给您带来了问题:

.RegisterType<IMyDbContext, MyDbContext>(new HttpContextLifetimeManager<IMyDbContext>())

我们的代码中也有类似的问题,因为DbContext不是线程安全的,但在不同的请求之间共享它通常不是一个好主意。相反,我们这样做了,并且没有任何连接问题:

.RegisterType<IMyDbContext, MyDbContext>(new PerRequestLifetimeManager())

这样,每个请求都会创建一个新的上下文实例。此外,DbContext实现IDisposable,因此如果您想手动控制DbContext的实例化和处理,那么您可以简单地执行:

using (var context = new MyDbContext())
{
}

我发现了问题,我们有一个CustomFilterAttribute,如下所示:

public class CustomFilters : ActionFilterAttribute
{
    [Dependency]
    public ICustomersService CustomersService { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)

如果我删除这个过滤器并覆盖Controller中的OnActionExecuting,那么它将不会出现问题

我们正在使用此提供程序将类型注入过滤器

public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider
{
    private IUnityContainer _container;
    public UnityFilterAttributeFilterProvider(IUnityContainer container)
    {
        _container = container;
    }
    protected override IEnumerable<FilterAttribute> GetControllerAttributes(
        ControllerContext controllerContext,
        ActionDescriptor actionDescriptor)
    {
        var attributes = base.GetControllerAttributes(controllerContext,
            actionDescriptor);
        foreach (var attribute in attributes)
        {
            _container.BuildUp(attribute.GetType(), attribute);
        }
        return attributes;
    }
    protected override IEnumerable<FilterAttribute> GetActionAttributes(
        ControllerContext controllerContext,
        ActionDescriptor actionDescriptor)
    {
        var attributes = base.GetActionAttributes(controllerContext,
            actionDescriptor);
        foreach (var attribute in attributes)
        {
            _container.BuildUp(attribute.GetType(), attribute);
        }
        return attributes;
    }
}

我们使用以下

        var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
        FilterProviders.Providers.Remove(oldProvider);
        var container = new UnityContainer();
        var provider = new UnityFilterAttributeFilterProvider(container);
        FilterProviders.Providers.Add(provider);
        UnityConfig.RegisterTypes(container);
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

我们还更改了使用"PerrequestLifeTimeManager"注册的所有类型,但没有任何更改,这有什么问题?