无法可靠地查询EntityFramework共享dbcontext

时间:2011-10-04 17:40:46

标签: entity-framework objectcontext dbcontext objectdisposedexception code-first

我正在尝试在多个存储库之间共享一个带有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()
}
  

测试方法   Tests.Service.TestDelete   抛出异常:System.ObjectDisposedException:ObjectContext   实例已被处理,不能再用于操作   这需要连接。

如果数据库已存在,则代码按预期执行。当我将GetEntityByName(字符串名称)的实现更改为以下非执行代码时,它也可以工作

public IOfferResult GetEntityByName(string name)
{
   foreach (OfferResult offer in Context.Offers)
   {
       if (offerName.ToLower() == offer.Name.ToLower())
       {
           return offer;
       }
   }
}

问题:这里发生了什么?

请记住,如果在运行测试时数据库存在,我根本不会收到错误。

TIA, JT

1 个答案:

答案 0 :(得分:3)

出现这个问题是因为你通过将DbContext声明为一个static字段来处理CodeFirstRepository,但是你将它当作一个瞬态实例来处理,只需将它处理掉即可 using (var r = new PersonRepository()) { // do something } // When you hit the end of this block, your static DbContext is disposed. using (var r = new IOfferRepository()) { r.GetEntityByName("test"); // this will fail because the context is still disposed. } 的任何实例都会被处置。例如:

DbContext

您应该以这种方式共享上下文。如果您确实希望所有存储库都使用Context.Dispose()的单个实例,请删除对DbContext的调用。这样可以解决您现在遇到的问题,但将来可能会引入其他问题。

但是我强烈建议在多个线程可能尝试同时访问它的情况下使用单个DbContext。根据{{​​1}} specs

  

不保证所有实例成员都是线程安全的。

最好只从您的字段中删除static关键字。