2

Ниже приведена моя рабочая единица работы, и я использую Ninject, и я попытался ввести инъекцию IUnitOfWork на запрос на область потока, переходный процесс и т. Д., Но я все еще получаю ошибку который является:Entity Framework Контекст не может использоваться во время создания модели

"Message": "has occurred An error", "ExceptionMessage": "context не можете be used while model является being created Это exception may be thrown если context будет used inside. Метод OnModelCreating или если один и тот же экземпляр контекста обращается одновременно несколькими потоками. Обратите внимание, что члены экземпляра DbContext и связанные классы не гарантируются потокобезопасностью. "," ExceptionType ":" System.InvalidOperationException

Я получаю эту ошибку, когда я сделать два веб-API (получить) вызывает в то же самое время, используя angularJS и он показывает ошибку в точке _context.Set<TEntity>().FirstOrDefault(match);

public class UnitOfWork : IUnitOfWork, IDisposable 
{ 
    private My_PromotoolEntities _uowDbContext = new My_PromotoolEntities(); 

    private Dictionary<string, object> _repositories; 


    // Do it like this if no specific class file 
    private GenericRepository<MysPerson> _personRepository; 
    //private GenericRepository<MysDataSource> dataSourcesRepository; 
    //private GenericRepository<MysCountry> countryMasterRepository; 


    // Or like this if with specific class file. 
    private DataSourceRepository _dataSourcesRepository; 
    private CustomerRepository _customerRepository; 
    private DeviceRepository _deviceRepository; 
    private DeviceRegistrationRepository _deviceRegistrationRepository; 
    private EmailQueueRepository _emailQueueRepository; 


    public void SetContext(My_PromotoolEntities context) 
    { 
     _uowDbContext = context; 
    } 


    public void CacheThis(object cacheThis, string keyName, TimeSpan howLong) 
    { 
     Cacheing.StaticData.CacheStaticData(cacheThis, keyName, howLong); 
    } 
    public object GetFromCache(string keyName) 
    { 
     return Cacheing.StaticData.GetFromCache(keyName); 
    } 


    public GenericRepository<T> GenericRepository<T>() where T : BaseEntity 
    { 
     if (_repositories == null) 
     { 
      _repositories = new Dictionary<string, object>(); 
     } 

     var type = typeof(T).Name; 

     if (!_repositories.ContainsKey(type)) 
     { 
      var repositoryType = typeof(GenericRepository<>); 
      var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)), _uowDbContext); 
      _repositories.Add(type, repositoryInstance); 
     } 
     return (GenericRepository<T>)_repositories[type]; 
    } 

    public GenericRepository<MysPerson> PersonRepository 
    { 
     get 
     { 
      if (this._personRepository == null) 
      { 
       this._personRepository = new GenericRepository<MysPerson>(_uowDbContext); 
      } 
      return _personRepository; 
     } 
    } 
    public DataSourceRepository DataSourcesRepository 
    { 
     get 
     { 
      if (this._dataSourcesRepository == null) 
      { 
       this._dataSourcesRepository = new DataSourceRepository(_uowDbContext); 
      } 
      return _dataSourcesRepository; 
     } 
    } 
    public CustomerRepository CustomerRepository 
    { 
     get 
     { 
      if (this._customerRepository == null) 
      { 
       this._customerRepository = new CustomerRepository(_uowDbContext); 
      } 
      return _customerRepository; 
     } 
    } 
    public DeviceRepository DeviceRepository 
    { 
     get 
     { 
      if (this._deviceRepository == null) 
      { 
       this._deviceRepository = new DeviceRepository(_uowDbContext); 
      } 
      return _deviceRepository; 
     } 
    } 
    public DeviceRegistrationRepository DeviceRegistrationRepository 
    { 
     get 
     { 
      if (this._deviceRegistrationRepository == null) 
      { 
       this._deviceRegistrationRepository = new DeviceRegistrationRepository(_uowDbContext); 
      } 
      return _deviceRegistrationRepository; 
     } 
    } 

    public EmailQueueRepository emailQueueRepository 
    { 
     get 
     { 
      if (this._emailQueueRepository == null) 
      { 
       this._emailQueueRepository = new EmailQueueRepository(_uowDbContext); 
      } 
      return _emailQueueRepository; 
     } 
    } 




    /// <summary> 
    /// Commits all changes to the db. Throws exception if fails. Call should be in a try..catch. 
    /// </summary> 
    public void Save() 
    { 
     try 
     { 
      _uowDbContext.SaveChanges(); 
     } 
     catch (DbEntityValidationException dbevex) 
     { 
      // Entity Framework specific errors: 

      StringBuilder sb = new StringBuilder(); 
      var eve = GetValidationErrors(); 
      if (eve.Count() > 0) 
      { 
       eve.ForEach(error => sb.AppendLine(error)); 
      } 

      ClearContext(); 

      // Throw a new exception with original as inner. 
      var ex = new Exception(sb.ToString(), dbevex); 
      ex.Source = "DbEntityValidationException"; 
      throw ex; 
     } 
     catch (Exception) 
     { 
      ClearContext(); 
      throw; 
     } 
    } 

    private void ClearContext() 
    { 
     DetachAll(); 
    } 

    private void DetachAll() 
    { 
     foreach (DbEntityEntry dbEntityEntry in _uowDbContext.ChangeTracker.Entries()) 
     { 

      if (dbEntityEntry.Entity != null) 
      { 
       dbEntityEntry.State = EntityState.Detached; 
      } 
     } 
    } 

    /// <summary> 
    /// Checks for EF DbEntityValidationException(s). 
    /// </summary> 
    /// <returns>Returns a List of string containing the EF DbEntityValidationException(s).</returns> 
    public List<string> GetValidationErrors() 
    { 
     if (_uowDbContext.GetValidationErrors().Count() != 0) 
     { 
      return _uowDbContext.GetValidationErrors().Select(e => string.Join(Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))).ToList(); 
     } 
     return null; 
    } 



    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       _uowDbContext.Dispose(); 
      } 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

ответ

0

Вы никогда не должны использовать контекст в 2 местах одновременно, именно поэтому вы получаете эту ошибку. От MSDN documentation:

Безопасность нитей: любые публичные статические (Shared in Visual Basic) элементы этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.

+0

Спасибо, пожалуйста, объясните, как я использую контекст в двух местах. – Salman

+0

Невозможно сказать из этого кода, я полагаю, вы вводите общий копия 'IUnitOfWork'. – DavidG

+0

Я искал весь мой код и только место, где я мог найти ссылку, был в ninjectWebCommon, который является kernel.Bind () .To (); – Salman

0

Немного сложно сделать предложения без повторного воспроизведения, но есть подход грубой силы, который должен решить проблему. Если у вас есть точка перехвата до/во время установки DI, вы можете вызвать всю инициализацию контекста и т. Д., Создав экземпляр вашего контекста и вызывая ctx.Database.Initialize (force: false); Передача «force: false» будет гарантировать, что инициализация будет выполняться только один раз за AppDomain

Смежные вопросы