使用声明的范围

时间:2016-03-04 07:02:01

标签: c# using

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

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()时,正在生成选择并且正在从数据库中检索数据。

问题:using (myEntities ctx = new myEntities())的范围是否适用于实现?

一方面它是schuld因为它管理数据库的选择/连接并且在物化时生成 - 另一方面它在方法之外被调用,并且可以在代码中的任何地方 - 在using指令之外

2 个答案:

答案 0 :(得分:7)

不,using语句不能一直存在于查询的具体化中。

除非调用Person已经返回一个完全物化的集合,这不太可能而且不典型。

以下是:

  1. 构建上下文
  2. 您调用上下文的Person属性,并查看LINQ查询

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

  3. 您处置上下文
  4. 您返回构建的LINQ查询
  5. 您在查询上调用FirstOrDefault,尝试执行它
  6. 此时可能的结果是代码崩溃,因为您尝试使用已经处理的上下文执行查询。

答案 1 :(得分:1)

以下是如何进行使用工作:

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();
    }
}