c# - LINQ 如何在 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(var row in result)
   {
      //Do something
   }
}

根据文档,linq 执行将推迟到我实际枚举结果时,该结果出现在 foreach 的行中。但是,using 语句应强制在调用 MyFunct() 结束时可靠地收集对象。

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

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

编辑:注意:此代码确实有效,我只是不明白如何。

我做了一些阅读,并在我的代码中意识到我调用了 ToList() 扩展方法,该方法当然会枚举结果。勾选答案的行为对于回答的实际问题是完全正确的。

抱歉造成任何混淆。

最佳答案

我希望这根本行不通; Select被延迟,所以此时没有数据被消耗。但是,由于您已经处理了数据上下文(在离开 MyFunc 之前),它将永远无法获取数据。更好的选择是将数据上下文传递给方法,以便消费者可以选择生命周期。另外,我建议返回 IQueryable<T>以便消费者可以“组合”结果(即添加 OrderBy/Skip/Take/Where 等,并使其影响最终查询):

// this could also be an instance method on the data-context
internal static IQueryable<SomeType> MyFunc(
    this MyDataContext dc, parameter a)
{
   return dc.tablename.Where(row => row.parameter == a);
}

private void UsingFunc()
{
    using(MyDataContext dc = new MyDataContext()) {
       var result = dc.MyFunc(new a());

       foreach(var row in result)
       {
           //Do something
       }
    }
}

更新:如果您(评论)不想延迟执行(即您不希望调用者处理数据上下文),那么您需要评估结果。您可以通过调用 .ToList() 来完成此操作或 .ToArray()在结果上缓冲值。

private IEnumerable<SomeType> MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      // or ToList() etc
      return dc.tablename.Where(row => row.parameter == a).ToArray();
   }
}

如果你想在这种情况下保持延迟,那么你需要使用“迭代器 block ”:

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

这现在在不传递数据上下文的情况下被推迟。

关于c# - LINQ 如何在 using 语句中延迟执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/456691/

相关文章:

c# - 坚持 C# 正则表达式

c# - 为什么 C# 代码不从存储过程返回值

c# - 在运行时创建具有不同资源的 exe 副本

c# - PixelFormat.Format32bppArgb 似乎有错误的字节顺序

c# - 以 XML 形式存储的查询字符串属性

c# - 重构 foreach 和 if's 到 Linq

c# - 只有字符串时传递泛型 'class'

c# - 将excel中的数据导入到多个表中

c# - .NET Regex - 一次替换多个字符而不覆盖?

c# - 如果结果为 NULL,LINQ 会在 Any() 上出错