C# 实体框架支持多线程吗?

C# 实体框架支持多线程吗?,c#,multithreading,entity-framework,C#,Multithreading,Entity Framework,我正在编写一个C#.NET4.5控制台应用程序,目标是实体框架6.1.3。 我使用的工作单元范例如下: public class UnitOfWork : IUnitOfWork, IDisposable { private readonly DataContext _context; private readonly List<object> _repositories = new List<object>(); public UnitOfWor

我正在编写一个C#.NET4.5控制台应用程序,目标是实体框架6.1.3。 我使用的工作单元范例如下:

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; }
    }
公共类UnitOfWork:IUnitOfWork,IDisposable
{
私有只读数据上下文_上下文;
私有只读列表_repositories=new List();
公共UnitOfWork(DataContext上下文)
{
_上下文=上下文;
_context.Configuration.LazyLoadingEnabled=false;
}
公共IRepository GetRepository(),其中T:class
{
//尝试获取现有存储库
var repo=(IRepository)\ u存储库。SingleOrDefault(r=>r为IRepository);
if(repo==null)
{
//如果未找到,请创建它并添加到列表中
_Add(repo=newentityrepository(_context));
}
回购回报;
}
公共int提交()
{
返回_context.SaveChanges();
}
公共布尔值自动检测更改
{
获取{return\u context.Configuration.AutoDetectChangesEnabled;}
设置{u 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();
公共类实体存储:i存储,其中T:class
{
受保护的只读DbContext上下文;
受保护的只读数据库集;
公共实体报告(DbContext)
{
上下文=上下文;
DbSet=Context.Set();
}
公共IQueryable All()
{
返回DbSet;
}
……其他功能…。
公共虚拟空添加(T实体)
{        
DbEntityEntry DbEntityEntry=Context.Entry(实体);
if(dbEntityEntry.State!=EntityState.Distached)
{
dbEntityEntry.State=EntityState.Added;
}
其他的
{
添加(实体);
}
}
}
我这样称呼他们:

   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();
var rep=_uow.GetRepository();
代表添加(饼图);
_提交();
我的控制台应用程序有多个线程,每个线程在某个时候都希望更新/编辑/添加到基于云的SQL Server数据库中的相同表中

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

内部异常:由于会话中正在运行其他线程,因此不允许新事务。

我在网上查过,没有找到太多关于实体和多线程的信息。我听说实体不支持多线程应用程序,但我发现大家都相信这一点。如果有任何提示,我将不胜感激。

各州的文档:

任何实例成员都不能保证线程安全

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


您必须在每个线程中创建一个新的DataContext实例。

Wow。这是一个简单的解决方案…我想我必须回到SQL:)。每个线程一个DataContext。很好。我会尝试。我会注意到多线程只会改进CPU限制的任务。因为数据库任务通常是I/O限制的(对于“云”数据库更是如此)多线程可能没有多大帮助,如果多线程的开销超过了任何好处,则情况可能会更糟。@DStanley这不完全正确。我一直在I/O任务上使用多线程,并发现了巨大的好处。好处是,当您等待一个查询的答复时,您可以准备并发送下一个查询。当然,这实际上并不依赖于多个线程。它更像是多任务,尽管看起来通常是一样的。为此,我非常喜欢.NET中的新任务库。我将其编码为多线程,但框架会考虑它实际使用的线程数。