无法可靠地查询 EntityFramework 共享 dbcontext
我正在尝试在多个存储库之间共享一个带有 4 个 DbSet 的简单 DbContext,我的每个存储库都继承自该基类
public class CodeFirstRepository : IDisposable
{
private static MyContext _ctx = new MyContext();
protected MyContext Context
{
get { return _ctx; }
}
public void Dispose()
{
if (Context != null)
{
Context.Dispose();
}
}
}
问题:这是在存储库之间共享连接的适当方法吗?
访问各个存储库时,我的单元测试中出现间歇性失败。存储库方法 GetEntityByName 引发异常
public IOfferResult GetEntityByName(string name)
{
return Context.Entities.Where(o => o.Name == name).FirstOrDefault()
}
测试方法 测试.服务.测试删除 抛出异常:System.ObjectDisposeException:ObjectContext 实例已被处置,不能再用于操作 需要连接。
如果数据库已存在,则代码按预期执行。当我将 GetEntityByName(string name) 的实现更改为以下非性能代码时,它也有效
public IOfferResult GetEntityByName(string name)
{
foreach (OfferResult offer in Context.Offers)
{
if (offerName.ToLower() == offer.Name.ToLower())
{
return offer;
}
}
}
问题:这里发生了什么?
请记住,如果我运行测试时数据库存在,我根本不会收到错误。
蒂亚, 杰特
I'm trying to share a simple DbContext with 4 DbSets among multiple repositories, each of my repositories inherit from this base class
public class CodeFirstRepository : IDisposable
{
private static MyContext _ctx = new MyContext();
protected MyContext Context
{
get { return _ctx; }
}
public void Dispose()
{
if (Context != null)
{
Context.Dispose();
}
}
}
Question: is this an appropriate way to share a connection between repositories?
I'm getting intermittent failures in my unit tests when accessing the various repositories. An exception is thrown from the repository method GetEntityByName
public IOfferResult GetEntityByName(string name)
{
return Context.Entities.Where(o => o.Name == name).FirstOrDefault()
}
Test method
Tests.Service.TestDelete
threw exception: System.ObjectDisposedException: The ObjectContext
instance has been disposed and can no longer be used for operations
that require a connection.
if the database already exists, the code executes as expected. it also works when i change the implementation of GetEntityByName(string name) to the following non-performant code
public IOfferResult GetEntityByName(string name)
{
foreach (OfferResult offer in Context.Offers)
{
if (offerName.ToLower() == offer.Name.ToLower())
{
return offer;
}
}
}
Question: what is going on here?
bear in mind that if the database exists when i run the tests i don't get the error at all.
tia,
jt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
出现此问题的原因是,您将 DbContext 视为单例,将其声明为静态字段,但随后通过处置它,将其视为瞬态实例一旦
CodeFirstRepository
的任何实例被释放。例如:您不应该以这种方式不共享上下文。如果您确实希望所有存储库都使用
DbContext
的单个实例,请删除对Context.Dispose()
的调用。这可以解决您现在遇到的问题,但将来可能会带来其他问题。但我强烈警告不要在多个线程可能尝试同时访问单个 DbContext 的情况下使用它。根据
DbContext
规格:您最好从字段中删除
static
关键字。This problem is arising because you are treating the
DbContext
like a singleton by declaring it as astatic
field, but then you are treating it like it like a transient instance by disposing it as soon as any instance ofCodeFirstRepository
gets disposed. For example:You should not share contexts this way. If you really want all of your repositories to use a single instance of the
DbContext
, remove the call toContext.Dispose()
. This would fix the problem you're getting right now, but it will likely introduce other problems in the future.But I would strongly caution against using a single
DbContext
in a scenario where multiple threads could be trying to access it simultaneously. According to theDbContext
specs:You'd be better off just removing the
static
keyword from your field.