实体框架,Linq,ObjectContext和延迟执行问题?

时间:2009-03-16 18:05:52

标签: linq entity-framework

我是Linq to EntityFramework的新手,Linq2EntityFramework中的一个问题是我何时或是否要处置ObjectContext。我问这个问题的原因是通常在我的DAL中我有像

这样的代码
public List<User>  GetUsers()
{
    using (MyEntities db = new MyEntities())   //where MyEntities inherits ObjectContext. 
    {

       // do some linq select operation which returns IQueryable<User>
       // call ToList() on the return IQueryable which is when the DB is really accessed
       // then we return List<User>

    } 
    // after using statement a Dispose method on ObjectContext is called, hence disposed the ObjectContext,  and in turn it closes my DB connection and releases it to the pool
}

现在,我不想这样做,我希望我的DAL返回IQueryable到我的BLL而不是List,这样我的BLL可以像返回的IQueryable上的Skip()那样进行过滤,然后在BLL中调用ToList() 。所以代码变成这样,

public IQueryable<User>  GetUsers()
{
   // do some linq select operation which returns IQueryable<User>
   // then just return what we got back
   // Note: no DB access occurred here, this is called deferred execution, because the real DB access happens later in BLL
}

然后在我的BLL中我有一个类似

的方法
public List<User>  GetUsers()
{
   // get IQueryable<User> from DAL to a var say users     
    return  users.Skip(10).Take(20).ToList(); // here the DB access really happens.  Note: if we put using in DAL, here will throw exception saying DB is already closed!!
}

我的问题是,

  1. 如果我使用第二种方法,Linq2EF会在上述方法完成后知道关闭我的连接吗?
  2. 使用第二种方法,ObjectContext永远不会被处置,这会对大型网站造成问题吗?
  3. 或者我如何获得IQuerayable但仍然在DAL中处理ObjectContext?
  4. 非常感谢, 射线。

    编辑:我不明白的一件事是,如果连接是由ObjectContext巧妙管理的,那么可以不处理ObjectContext吗? ObjectContext旁边还有哪些东西可以管理?

4 个答案:

答案 0 :(得分:2)

关于你的问题:

  1. 它将关闭打开并关闭与ToList的连接,因为所有枚举都发生在那个地方。只有这样才能让你有一个长时间打开的连接,如果你枚举它并为每个项目运行一些半长处理。
  2. 对于正常的大型网站和正常运营,您可以这样做。可能让您遇到麻烦的主要因素是实体跟踪,它涉及您已加载的任何实体。如果您要么加载太多信息,要么拥有一个非常大的网站,您可以避免使用它(不要为正常网站冒汗)。
  3. 您可以让您的数据访问类实现IDisposable,并在处理数据文本时处置它。因此,在您的GetUsers中,您可以改为使用数据访问类。

答案 1 :(得分:1)

我倾向于将EF ObjectContext 视为 DAL,它解决了这个问题。如果你想让你自己的DAL封装EF的东西(不是一个可怕的想法,IMO),我建议你的DAL实现IDisposable。

答案 2 :(得分:1)

如果您在网站的上下文中,您应该认真考虑在整个请求期间使您的ObjectContext存活。

你需要保持ObjectContext的延迟加载,现在就可以了。

在查询和SaveChanges期间根据需要打开和关闭连接,因此您不应该有“连接泄漏”。

答案 3 :(得分:0)

如果你想和IQueryable你可以通过查询ToList()结果并返回

来做到这一点