Платформа сущностей с Unity «Базовый поставщик не удалось открыть». - PullRequest
0 голосов
/ 28 октября 2019

Я работаю над обновлением проектов одной из своих компаний до более новых версий MVC, Entity Framework и Unity. Большая часть работы была завершена, однако, у меня есть эта проблема при загрузке данных из базы данных. Это не происходит при каждом запросе, и большинство приложений работает нормально. Проблема возникает при вызовах API, выполняемых приложением при наличии нескольких одновременных вызовов.

Я пытался переключить LifeTimeManager контейнеров Unity на разные типы с разными результатами (ни один из них на самом деле не решил проблему).

Это мой класс DataContext

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

    }

Это мой 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()
            );
        }
    }

Строка подключения: Data Source=LOCALHOST;Initial Catalog=Database;Integrated Security=true;MultipleActiveResultSets=True

Сообщение об ошибке: The underlying provider failed on Open.

1 Ответ

0 голосов
/ 28 октября 2019

вызов dbContext.Connection.Open(); метода после инициализации вашей переменной dbContext. Это откроет соединение для EF

...