Which LINQ statements force Entity Framework to return from the DB?

前端 未结 4 1467
旧巷少年郎
旧巷少年郎 2020-12-09 10:02

I know of several LINQ statements that will cause EF to evaluate and return results form the DB to memory. .ToList() is one. Does anyone have a comprehensive

相关标签:
4条回答
  • 2020-12-09 10:14

    Anything that returns a concrete object or data structure (Count, Sum Single, First, ToList, ToArray, etc.) is evaluated immediately, so SingleOrDefault certainly does.

    Anything that returns an IQueryable<T> (Select, GroupBy, Take) will be deferred (so that operations can be chained), so Queryable.Union will be deferred.

    Anything that returns an IEnumerable<T> will also be deferred, but subsequent queries will be done in Linq-to-objects, so subsequent operations won't be translated to SQL. (Empty is an exception since there's not really anything to defer - it just returns an empty collection)

    0 讨论(0)
  • 2020-12-09 10:18

    It's a long list. They boil down to

    Aggregate
    All<TSource>
    Any
    Average
    Contains
    Count
    ElementAt<TSource>
    ElementAtOrDefault<TSource>
    Empty<TResult>
    First
    FirstOrDefault
    Last
    LastOrDefault
    LongCount
    Max
    Min
    SequenceEqual
    Single
    SingleOrDefault
    Sum
    ToArray<TSource>
    ToDictionary
    ToList<TSource>
    ToLookup
    

    The rest are either Deferred Streaming Execution or Deferred Non-Streaming Execution.

    In light of your question, SingleOrDefault() is Immediate Execution and Union() is Deferred Streaming Execution.

    0 讨论(0)
  • 2020-12-09 10:20

    From MSDN,

    Queries that perform aggregation functions over a range of source elements must first iterate over those elements.

    Examples of such queries are Count, Max, Average, and First. These execute without an explicit foreach statement because the query itself must use foreach in order to return a result.

    Note also that these types of queries return a single value, not an IEnumerable collection.

    To force immediate execution of any query and cache its results, you can call the ToList<TSource> or ToArray<TSource> methods.

    0 讨论(0)
  • 2020-12-09 10:28

    In the case of Entity Framework, there's an easy way to refresh your memory.

    Entity Framework has Async variants of all such methods defined in System.Data.Entity, because Async doesn't make sense with the others as it's the very act of querying the database that the Async variants do asynchronously.

    So if there's an Async variant, then it hits the database and otherwise it does not.

    Enumerating or producing an IEnumerable<T> is a part-way case though: The act of obtaining an IEnumerable<T> obtaining its enumerator (as happens at the start of foreach blocks) does not hit the database, but the first MoveNext() (which happens immediately within the foreach does hit the database, and it then continues to stream from the resultset until either MoveNext() returns false (as when the foreach reaches a "natural" end) or the enumerator is disposed prior to that (as when the foreach is aborted).

    0 讨论(0)
提交回复
热议问题