C# LINQ在using语句中如何延迟执行

C# LINQ在using语句中如何延迟执行,c#,.net,linq,idisposable,using,C#,.net,Linq,Idisposable,Using,假设我有以下几点: private IEnumerable MyFunc(parameter a) { using(MyDataContext dc = new MyDataContext) { return dc.tablename.Select(row => row.parameter == a); } } private void UsingFunc() { var result = MyFunc(new a()); foreach(va

假设我有以下几点:

private IEnumerable MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      return dc.tablename.Select(row => row.parameter == a);
   }
}

private void UsingFunc()
{
   var result = MyFunc(new a());

   foreach(var row in result)
   {
      //Do something
   }
}
根据文档,linq的执行将推迟到我实际枚举结果时,结果发生在foreach的行中。但是,using语句应该强制在调用MyFunct()结束时可靠地收集对象

实际会发生什么,处理器何时运行和/或结果何时运行

我唯一能想到的是,延迟执行是在编译时计算的,因此编译器将实际调用移动到foreach的第一行,从而导致using正确执行,但直到foreach行才运行? 有没有可以帮忙的大师

编辑:注意:这段代码确实有效,我只是不明白怎么做

我读了一些书,在我的代码中意识到我调用了ToList()扩展方法,该方法当然会枚举结果。勾选答案的行为完全符合所回答的实际问题


很抱歉给您带来任何困惑。

我认为这根本不起作用;
Select
延迟,因此此时未使用任何数据。但是,由于您已经处理了数据上下文(在离开
MyFunc
之前),它将永远无法获取数据。更好的选择是将数据上下文传递到方法中,以便使用者可以选择生存期。此外,我建议返回
IQueryable
,以便消费者可以“合成”结果(即添加
OrderBy
/
跳过
/
在哪里取
/
等,并使其影响最终查询):

在这种情况下,如果要使其延迟,则需要使用“迭代器块”:

private IEnumerable MyFunc(参数a)
{
使用(MyDataContext dc=new MyDataContext)
{
foreach(dc中的某个类型行)
.tablename.Where(row=>row.parameter==a))
{
收益返回行;
}
}
}

现在延迟执行,而不传递数据上下文。

我刚刚发布了另一个针对此问题的延迟执行解决方案,包括以下示例代码:

IQueryable<MyType> MyFunc(string myValue)
{
    return from dc in new MyDataContext().Use()
           from row in dc.MyTable
           where row.MyField == myValue
           select row;
}

void UsingFunc()
{
    var result = MyFunc("MyValue").OrderBy(row => row.SortOrder);
    foreach(var row in result)
    {
        //Do something
    }
}
IQueryable MyFunc(字符串myValue)
{
从新MyDataContext()中的dc返回。使用()
从dc.MyTable中的行开始
其中row.MyField==myValue
选择行;
}
使用func()无效
{
var result=MyFunc(“MyValue”).OrderBy(row=>row.SortOrder);
foreach(结果中的var行)
{
//做点什么
}
}

Use()。我想要的只是这些函数中的列表、可枚举项和标量。每次都会影响数据库吗?或者它会执行查询,然后返回每个值吗?它会在返回第一个结果后命中数据库。它会在每次返回时命中数据库吗?或者点击db一次,然后将结果保存在内存中?它会在每个调用方的“foreach”中点击db一次-然后在调用方的foreach期间有一个实时连接;迭代器块保证当调用方的foreach退出时,数据上下文关闭(从而连接关闭)。没有缓冲。问得好。我被这件事吓坏了。。一个Using(DataContext)使我大吃一惊,当我尝试这个时,我会得到一个ObjectDisposedException“DataContext在Dispose之后访问”。MyDataContext是从LINQ设计器自动生成的DataContext吗?它是否继承自DataContext?我的第三个概念是:如果您使用“using”来处理DataContext,那么如果您稍后尝试使用DataContext,您将得到一个运行时异常。我知道我已经做到了。向所有人道歉,看我更新的问题,你完全正确。我已经接受了答案,但这是一种非常巧妙的思维方式。使用()扩展方法。对于这样的答案,你应该得到比a+1更多的答案。对于像“MyDataContext().Use()”这样的人,还有一个额外的网站吗?!
private IEnumerable<SomeType> MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      // or ToList() etc
      return dc.tablename.Where(row => row.parameter == a).ToArray();
   }
}
private IEnumerable<SomeType> MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      foreach(SomeType row in dc
          .tablename.Where(row => row.parameter == a))
      {
        yield return row;
      }
   }
}
IQueryable<MyType> MyFunc(string myValue)
{
    return from dc in new MyDataContext().Use()
           from row in dc.MyTable
           where row.MyField == myValue
           select row;
}

void UsingFunc()
{
    var result = MyFunc("MyValue").OrderBy(row => row.SortOrder);
    foreach(var row in result)
    {
        //Do something
    }
}