2016-04-26 81 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。尼斯。我會嘗試。 –