当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《LINQ如何在using语句中延迟执行》经验,为你挑选了2个好方法。

想象一下,我有以下几点:

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的第一行,导致使用正确执行,但直到foreach行才运行?那里有一位可以提供帮助的大师吗?

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

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

对不起任何困惑.



1> Marc Gravell..:

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

// this could also be an instance method on the data-context
internal static IQueryable 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 MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      // or ToList() etc
      return dc.tablename.Where(row => row.parameter == a).ToArray();
   }
}

如果你想在这种情况下延迟它,那么你需要使用"迭代器块":

private IEnumerable MyFunc(parameter a)
{
   using(MyDataContext dc = new MyDataContext)
   {
      foreach(SomeType row in dc
          .tablename.Where(row => row.parameter == a))
      {
        yield return row;
      }
   }
}

现在推迟了,而没有传递数据上下文.



2> dahlbyk..:

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

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

Use()扩展方法本质上的作用就像一个延迟using块.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有