C# 实体框架支持多线程吗?
我正在编写一个C#.NET4.5控制台应用程序,目标是实体框架6.1.3。 我使用的工作单元范例如下: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
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中的新任务库。我将其编码为多线程,但框架会考虑它实际使用的线程数。