【问题标题】:FirstorDefault() causes lazy loading or eager loading for linq to sqlFirstorDefault() 导致 linq to sql 的延迟加载或急切加载
【发布时间】:2013-05-31 14:48:14
【问题描述】:

FirstOrDefault() 与 Linq to SQL 一起使用时的默认行为是什么?

例如

  int value =   (from p in context.tableX         
                select p.Id).FirstOrDefault()      // Value will initialized here or

   if(value > 0)                      // query will be executed here????
   {
    //do something
   }

谢谢

【问题讨论】:

  • 只有实体和IEnumerable 被延迟加载。

标签: linq c#-4.0 linq-to-sql


【解决方案1】:

FirstOrDefault() 与 Linq to SQL 一起使用时的默认行为是什么?

它急切地计算查询的结果。考虑这一点的最简单方法是意识到返回类型是int,而不是IEnumerable<int>可以推迟到调用GetEnumerator,但int 没有这样的机制。

您问题的措辞表明您也在询问是否有办法改变这种行为。有,但不是直接通过FirstOrDefault 或 LINQ 中的任何机制。但您可以使用Lazy<T> 推迟。没有方便的编译器,所以如果它不能编译,请原谅我,但它应该让你非常接近。

Lazy<int> value = new Lazy<int>(
    () => {
        var query =
            from p in context.tableX
            select p.Id;
        var result = query.FirstOrDefault();
        return result;
    }
);

if(value.Value > 0) { // execution will be deferred until here
    //
}

【讨论】:

  • @Iti Tyagi - 听起来您在询问 FirstOrDefault() 是否会发起对 GetEnumerator 的调用。 query.FirstOrDefault() 会导致延迟加载或急切加载(即它是否会调用 GetEnumerator)?我相信像 query.ToList() 这样的东西会强制加载 - FirstOrDefault() 会这样做吗?
【解决方案2】:

所有返回单一、不可枚举的结果的标准 Linq 运算符都会在查询被声明时立即执行。因此,FirstOrDefaultCountSum 等返回单个值的运算符会立即执行。

这是一篇不错的 MSDN 文章Classification of Standard Query Operators by Manner of Execution

【讨论】:

    【解决方案3】:

    急于加载!

    如果您考虑一下,它只会返回一个普通的 int - int 不可能代表“获得int 的方法”。 (这就是Lazy&lt;int&gt; 的用途……)

    【讨论】:

      【解决方案4】:

      当您对可枚举的结果使用扩展方法时,它会变成急切加载。如果您不使用这些扩展方法,它将是延迟加载,并且在您枚举 linq 结果之前,您实际上无法获取值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        相关资源
        最近更新 更多