LINQ to Entities 運算子分為立即執行 (如 First、Count) 與延遲執行 (如 Where、Take)。本文列舉常用運算子並附對應 T-SQL。
// First - 立即執行
Products first = ctx.Products.First(p => p.ProductID > 3);
/* SQL: SELECT TOP (1) ... WHERE [Extent1].[ProductID] > 3 */
// FirstOrDefault - 立即執行,找不到回傳 null
Products firstOrDefault = ctx.Products.FirstOrDefault(p => p.ProductID > 100);
// All - 所有元素滿足條件
bool all = ctx.Products.All(p => p.ProductID > 3);
/* SQL: CASE WHEN NOT EXISTS (SELECT ... WHERE NOT (ProductID > 3)) THEN 1 ELSE 0 END */
// Any - 至少一個元素滿足條件
bool any = ctx.Products.Any(p => p.ProductID > 3);
/* SQL: CASE WHEN EXISTS (SELECT ... WHERE ProductID > 3) THEN 1 ELSE 0 END */
decimal? avg = ctx.Products.Average(p => p.UnitPrice);
decimal? sum = ctx.Products.Sum(p => p.UnitPrice);
decimal? max = ctx.Products.Max(p => p.UnitPrice);
decimal? min = ctx.Products.Min(p => p.UnitPrice);
/* SQL: 皆使用 LEFT OUTER JOIN (SELECT AVG/SUM/MAX/MIN ...) */
int count = ctx.Products.Count(p => p.ProductID > 3);
long longCount = ctx.Products.LongCount(p => p.ProductID > 3);
/* SQL: COUNT / COUNT_BIG */
// Take - 延遲
IQueryable<Products> take = ctx.Products.Take(3);
/* SQL: SELECT TOP (3) ... */
// Skip - 延遲,需先排序
IQueryable<Products> skip = ctx.Products.OrderBy(p => p.UnitPrice).Skip(3);
/* SQL: 使用 ROW_NUMBER() OVER (ORDER BY UnitPrice) WHERE row_number > 3 */
// Distinct - 延遲
ObjectQuery<Products> distinct = ctx.Products.Distinct();
/* SQL: SELECT ... FROM [dbo].[Products] (無 DISTINCT 關鍵字,因主鍵唯一) */
// Union - 延遲,聯集並去重
ObjectQuery<Products> union = ctx.Products.Union(ctx.Products);
/* SQL: SELECT DISTINCT ... FROM (SELECT ... UNION ALL SELECT ...) AS [UnionAll1] */
// UnionAll - 延遲,聯集不去重 (EF 實際產生 UNION ALL)
ObjectQuery<Products> unionAll = ctx.Products.UnionAll(ctx.Products);
/* SQL: SELECT ... FROM (SELECT ... UNION ALL SELECT ...) AS [UnionAll1] */
// Concat - 延遲,串連 (行為同 UnionAll)
IQueryable<Products> concat = ctx.Products.Concat(ctx.Products);
/* SQL: 同上 UNION ALL */
// Intersect - 延遲,交集
ObjectQuery<Products> intersect = ctx.Products.Intersect(ctx.Products);
/* SQL: SELECT ... FROM (SELECT ... INTERSECT SELECT ...) AS [Intersect1] */
// Except - 延遲,差集
ObjectQuery<Products> except = ctx.Products.Except(ctx.Products);
/* SQL: SELECT ... FROM (SELECT ... EXCEPT SELECT ...) AS [Except1] */
理解各運算子的執行時機與產生的 SQL 模式,對於效能調優與正確性至關重要。立即執行運算子會觸發資料庫往返,延遲運算子則允許進一步組合。完整原始碼:https://www.bianceng.net/dotnet/201212/805.htm