简体   繁体   中英

Entity framework with Unity “The underlying provider failed on Open.”

I'm working on upgrading one of my companies projects to newer versions of MVC, Entity Framework and Unity. Most of the work has been completed however, I do have this problem when loading data from the database. This does not happen on every request and most of the application functions normally. The problem occurs on API calls the application does when there are a couple of concurrent calls.

I've tried switching the LifeTimeManager of the Unity containers to different types with different results (none of them actually fixed the problem).

This is my DataContext class

    public class DataContext : IUnitOfWork, IRepositoryFactory
    {
        private const string CONSTRING = "CONSTRING";
        private static volatile DbContext dbContext = new DbContext(CONSTRING);

        private static volatile ConcurrentBag<object> repositories = new ConcurrentBag<object>();

        public DbContext DbContext => dbContext;

        public DataContext()
        {
            Database.SetInitializer<DbContext>(null);
        }

        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }

        public void Dispose()
        {
            dbContext.Dispose();
        }

        public IRepository<T> CreateRepositoryFor<T>() where T : class, IEntity
        {

            var reposType = typeof(Repository<T>);

            var repos = (IRepository<T>)repositories.FirstOrDefault(r => r.GetType() == reposType);

            if (repos == null)
            {
                repos = new Repository<T>(dbContext.Set<T>());


                repositories.Add(repos);
            }

            return repos;
        }

    }

This is my UnityConfig

    public class UnityConfig
    {
        #region Unity Container
        private static readonly Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Configured Unity Container.
        /// </summary>
        public static IUnityContainer Container => container.Value;
        #endregion

        public static void RegisterTypes(IUnityContainer container)
        {
            RegisterDependencies(container);

            System.Web.Mvc.DependencyResolver.SetResolver(new UnityDependencyResolverAdapter(container));
            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
        }

        private static void RegisterDependencies(IUnityContainer unityContainer)
        {
            RegisterDataContextAndUnitOfWork(unityContainer);
            RegisterRepositories(unityContainer);
        }

        private static void RegisterDataContextAndUnitOfWork(IUnityContainer container)
        {
            container.RegisterType<IUnitOfWork, DataContext>(new ContainerControlledLifetimeManager());
            container.RegisterType<IRepositoryFactory, DataContext>(new ContainerControlledLifetimeManager());
            container.RegisterType<IChangeTracker, DataContext>(new ContainerControlledLifetimeManager());
            container.RegisterType(typeof (ICrudService<>), typeof (GenericCrudService<>));

        }

        private static void RegisterRepositories(IUnityContainer container)
        {
            // Haal MethodInfo op zodat we at runtime de static RegisterRepository<T> kunnen aanroepen
            var registerRepositoryMethodName = MemberNameHelper.GetActionName(() => RegisterRepository<IEntity>(container));
            var registerRepositoryMethodInfo = typeof(UnityConfig).GetMethod(registerRepositoryMethodName, BindingFlags.NonPublic | BindingFlags.Static);

            // Registreer een repository voor iedere IEntity class in Domain project
            foreach (var entityType in typeof(IEntity).Assembly.GetTypes().Where(t => typeof(IEntity).IsAssignableFrom(t)))
            {
                var registerRepositoryMethod = registerRepositoryMethodInfo.MakeGenericMethod(entityType);
                registerRepositoryMethod.Invoke(null, new object[] { container });
            }
        }

        private static void RegisterRepository<T>(IUnityContainer unityContainer) where T : class, IEntity
        {
            unityContainer.RegisterFactory<IRepository<T>>(
                factory => factory.Resolve<IRepositoryFactory>().CreateRepositoryFor<T>(),
                new ContainerControlledLifetimeManager()
            );
        }
    }

The connectionstring is: Data Source=LOCALHOST;Initial Catalog=Database;Integrated Security=true;MultipleActiveResultSets=True

The error message is: The underlying provider failed on Open.

call dbContext.Connection.Open(); method after initialize your dbContext variable. This will open connection for EF

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM