实体框架创建模型时不能使用上下文 [英] Entity Framework The context cannot be used while the model is being created

查看:89
本文介绍了实体框架创建模型时不能使用上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面提到了我的工作单元类,我正在使用Ninject,并且尝试在每个线程范围,瞬态等每个请求中注入IUnitOfWork,但是仍然出现错误:

My unit of work class is mentioned below and I am using Ninject and I have tried injecting IUnitOfWork per request per thread scope, transient etc. but I am still getting error which is:

"Message":发生错误.","ExceptionMessage":在创建模型时无法使用上下文.如果在OnModelCreating方法内部使用上下文,或者如果上下文相同,则可能引发此异常.多个线程同时访问上下文实例.请注意,不能保证DbContext和相关类的实例成员是线程安全的.," ExceptionType:" System.InvalidOperationException

"Message":"An error has occurred.","ExceptionMessage":"The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.","ExceptionType":"System.InvalidOperationException

当我使用angularJS同时进行两个Web API(get)调用时出现此错误,并且它在点_context.Set<TEntity>().FirstOrDefault(match);处显示错误

I get this error when i make two web API (get) calls at the same time using angularJS and it shows error at the point _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);
    }
}

推荐答案

永远不要同时在2个地方使用上下文,这就是为什么会出现此错误的原因.来自 MSDN文档:

You should never use a context in 2 places at the same time, that's exactly why you are getting this error. From the MSDN documentation:

线程安全:此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的. 不保证任何实例成员都是线程安全的.

这篇关于实体框架创建模型时不能使用上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆