使用范围声明

Scope of using statement

我有一个方法可以给我一个对象列表,例如

public IEnumerable<Person> GetPerson()
{
    using (myEntities ctx = new myEntities())
    {
        return ctx.Person.Where(x => x.Age < 50);
    }
}

我在别的地方用过这个方法

public void Main()
{
   var pList = GetPerson();
   pList = pList.Where(x => x.Age < 40);

   Person Item = pList.FirstOrDefault(); //materialization here
}

当我调用 FirstOrDefault() 时,正在生成 select 并且正在从数据库中检索数据。

问:using (myEntities ctx = new myEntities())的范围是否达到实体化?

一方面,它应该是因为它管理数据库的 select/connection 并且是在实现时生成的 - 另一方面,它是在方法之外调用的,可以在代码中的任何地方 -在使用指令之外

不,using 语句不会一直存在到查询的具体化。

除非 调用 Person 已经 return 是一个完全具体化的集合,这不太可能也不典型。

发生的情况如下:

  1. 你构建上下文
  2. 你调用context的Person 属性,然后tuck on LINQ query

    这可能会 return 一个尚未执行的延迟查询

  3. 您处理上下文
  4. 您 return 您构建的 LINQ 查询
  5. 您在查询上调用 FirstOrDefault,试图执行它

此时可能的结果是代码崩溃,因为您正尝试使用已释放的上下文执行查询。

以下是使 using 起作用的方法:

void Main()
{
    Person Item = UsingPerson(ps => ps.Where(x => x.Age < 40).Take(1)).FirstOrDefault();
}


public T[] UsingPerson<T>(Func<IQueryable<Person>, IQueryable<T>> project)
{
    using (myEntities ctx = new myEntities())
    {
        return project(ctx.Person.Where(x => x.Age < 50)).ToArray();
    }
}