Entity framework 无法完成该操作,因为DbContext已被释放-LifeStylePerwcfoOperation
我有一个WCF Web服务,目前遇到一些并发性问题。目前负荷较小,但预计在未来几天内将大幅增加 总体设置是WCF、实体框架6、依赖项注入(Castle Windsor)、UnitOfWork&Repository模式 我设置了一个并行访问服务的压力测试,我可以重新创建并发错误,例如Entity framework 无法完成该操作,因为DbContext已被释放-LifeStylePerwcfoOperation,entity-framework,dependency-injection,castle-windsor,dbcontext,unit-of-work,Entity Framework,Dependency Injection,Castle Windsor,Dbcontext,Unit Of Work,我有一个WCF Web服务,目前遇到一些并发性问题。目前负荷较小,但预计在未来几天内将大幅增加 总体设置是WCF、实体框架6、依赖项注入(Castle Windsor)、UnitOfWork&Repository模式 我设置了一个并行访问服务的压力测试,我可以重新创建并发错误,例如 提交数据库事务时报告了错误,但无法确定该事务在数据库服务器上是成功还是失败 已成功提交对数据库的更改,但更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:AcceptChanges
- 提交数据库事务时报告了错误,但无法确定该事务在数据库服务器上是成功还是失败
- 已成功提交对数据库的更改,但更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保键值是唯一的
- 属性“ID”是对象密钥信息的一部分,无法修改
- 无法完成该操作,因为DbContext已被释放
IocContainer.AddFacility<TypedFactoryFacility>();
IocContainer.Register(Component.For<IRepositoryFactory>().AsFactory());
IocContainer.Register(Component.For<IUnitOfWork>()
.ImplementedBy<UnitOfWork>)
/*.LifestylePerWcfOperation()*/);
IocContainer.Register(Component.For(typeof(IDbContext))
.ImplementedBy(dbContextType)
.DependsOn(Dependency.OnValue("connectionString", String.Format(ConfigurationManager.ConnectionStrings["---"].ConnectionString))));
/*.LifestylePerWcfOperation()*/
IocContainer.Register(Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.LifestyleTransient()
/*.LifestylePerWcfOperation()*/);
// Register the actual dbContextType so consuming applications can access it without an interface
IocContainer.Register(Component.For(dbContextType)
.Named(dbContextType.Name)
.DependsOn(Dependency.OnValue("connectionString", String.Format(ConfigurationManager.ConnectionStrings["----"].ConnectionString)));
/*.LifestylePerWcfOperation()*/
Repository.cs
public class Repository<T> : IRepository<T> where T : class
{
private readonly IDbSet<T> _dbset;
public Repository(IDbContext dbContext)
{
_dbset = dbContext.Set<T>();
}
public IQueryable<T> Query()
{
return _dbset.AsQueryable();
}
public virtual IEnumerable<T> GetAll()
{
return _dbset.AsEnumerable();
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual void Delete(ICollection<T> entities)
{
entities.ToList().ForEach(Delete);
}
}
公共类存储库:IRepository,其中T:class
{
专用只读IDbSet _dbset;
公共存储库(IDbContext dbContext)
{
_dbset=dbContext.Set();
}
公共IQueryable查询()
{
返回_dbset.AsQueryable();
}
公共虚拟IEnumerable GetAll()
{
返回_dbset.AsEnumerable();
}
公共虚拟空添加(T实体)
{
_添加(实体);
}
公共虚拟作废删除(T实体)
{
_删除(实体);
}
公共虚拟作废删除(ICollection实体)
{
entities.ToList().ForEach(删除);
}
}
如果需要,我可以添加更多代码。谢谢你能提供的任何帮助 回答您的问题: 1) 你将生活方式转变为生活方式的做法是正确的 2) 您正在从UnitOfWork中处理DBContext。DBContext由Windsor注入,因此Windsor将对其调用Dispose。使用windsor时,切勿处置注入的对象,只有在使用factory或Resolve创建对象时,才必须释放(而不是处置)该对象,以便windsor可以处置它 我希望通过LifeStylePerwcfoOperations和删除Dispose代码,代码应该可以正常运行 祝你好运,
Marwijn.我能够解决这个问题 Fix正是Marwijn提到的。修复后,我仍然得到一个类似的错误 最后的解决办法是接受每一次注册,使其成为一种生活方式。我注册了一些生命周期较短的对象,因此DbContext也开始处理这些对象
如果有人遇到此错误,并且您正在使用Castle/EF,请不要显式地处置DbContext(让Castle来做),并使一切都成为Lifestyle PerwcfoOperation。这应该可以解决问题。然后返回并有选择地重置您不希望成为lifestyle PerwcfoOperation的任何对象的生活方式,并确保它不会在运行过程中中断。您的DBContext注册没有指定生活方式,因此Windsor的默认设置将适用:Singleton。这肯定会引起问题。谢谢Marwijn!这确实是第一步。我还需要对代码进行一些其他更改,但这些更改没有发布在这里
public class Repository<T> : IRepository<T> where T : class
{
private readonly IDbSet<T> _dbset;
public Repository(IDbContext dbContext)
{
_dbset = dbContext.Set<T>();
}
public IQueryable<T> Query()
{
return _dbset.AsQueryable();
}
public virtual IEnumerable<T> GetAll()
{
return _dbset.AsEnumerable();
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual void Delete(ICollection<T> entities)
{
entities.ToList().ForEach(Delete);
}
}