2016-04-26 73 views
2

我正在编写一个针对Entity Framework 6.1.3的C#.NET4.5控制台应用程序。 我使用单位上班范例如下:实体框架是否支持多线程?

public class UnitOfWork : IUnitOfWork, IDisposable 
{ 
    private readonly DataContext _context; 
    private readonly List<object> _repositories = new List<object>(); 
    public UnitOfWork(DataContext context) 
    { 
     _context = context; 
     _context.Configuration.LazyLoadingEnabled = false; 
    } 

    public IRepository<T> GetRepository<T>() where T : class 
    { 
     //try to get existing repository 
     var repo = (IRepository<T>)_repositories.SingleOrDefault(r => r is IRepository<T>); 
     if (repo == null) 
     { 
      //if not found, create it and add to list 
      _repositories.Add(repo = new EntityRepository<T>(_context)); 
     } 
     return repo; 
    } 

    public int Commit() 
    { 
     return _context.SaveChanges(); 
    } 


    public bool AutoDetectChanges 
    { 
     get { return _context.Configuration.AutoDetectChangesEnabled; } 
     set { _context.Configuration.AutoDetectChangesEnabled = value; } 
    } 

我的存储库这样的:

public class EntityRepository<T> : IRepository<T> where T: class 
    { 
     protected readonly DbContext Context; 
     protected readonly DbSet<T> DbSet; 
    public EntityRepository(DbContext context) 
    { 
     Context = context;    
     DbSet = Context.Set<T>(); 
    } 

    public IQueryable<T> All() 
    { 
     return DbSet; 
    } 
    ….. other functions…. 

    public virtual void Add(T entity) 
    {   
     DbEntityEntry dbEntityEntry = Context.Entry(entity); 
     if (dbEntityEntry.State != EntityState.Detached) 
     { 
      dbEntityEntry.State = EntityState.Added; 
     } 
     else 
     { 
      DbSet.Add(entity); 
     } 
    } 
    } 

我把这些像这样:

var rep = _uow.GetRepository<TableOfPies>(); 
rep.Add(Pie); 
_uow.Commit(); 

我的控制台应用程序有多个线程,每个线程都会在某些时候想要更新/编辑/添加到基于云的SQL Server数据库中的相同表中。

我已经实现了使用锁的其他代码的线程安全代码,但我不知道如何让实体线程安全?现在,我得到以下错误:

INNER EXCEPTION: New transaction is not allowed because there are other threads running in the session.

我在网上看了看,一直没能找到很多有关实体和多线程。我听说实体不支持多线程应用程序,但发现听到相信。任何指针将不胜感激。

+0

我会注意到多线程只会改进_CPU绑定_任务。由于数据库任务通常是I/O绑定的(对于“云”数据库而言更是如此),多线程可能没有多大帮助,如果多线程的开销超过任何好处,甚至可能会更糟糕。 –

+0

@DStanley这并不完全正确。我始终对I/O任务使用多线程,并找到了巨大的好处。好处是,当你在等待一个查询的回复时,你可以准备并发送下一个查询。当然,这并不是真的依赖于多个线程。这更像是多任务处理,尽管它看起来一样。我真的很喜欢.NET中的新任务库。我的代码就好像它是多线程的,但是框架会考虑它实际使用的线程数量。 –

回答

5

的文档DataContext状态:

Any instance members are not guaranteed to be thread safe.

而这正是我所经历过。我试图做你正在做的事情,我看到了奇怪的错误,它们支持它不是线程安全的想法。

您将不得不在每个线程中创建一个新的DataContext实例。

+0

哇。这是一个简单的解决方案...我想我必须回到SQL :)。每个线程一个DataContext。尼斯。我会尝试。 –