鑑於所涉及的實體,稱爲水果:混合FUNC鍵,表達謂詞在LINQ to實體的查詢
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
public bool Edible { get; set; }
}
以下LINQ到實體查詢:
var familiesWithAllEdibleFruits = context
.Fruits
.GroupBy(fruit => fruit.Family)
.Where(group => group.All(fruit => fruit.Edible));
生成單個SQL語句選擇正確的記錄:
SELECT
[Project4].[C1] AS [C1],
[Project4].[Family] AS [Family],
[Project4].[C2] AS [C2],
[Project4].[Id] AS [Id],
[Project4].[Name] AS [Name],
[Project4].[Family1] AS [Family1],
[Project4].[Edible] AS [Edible]
FROM (SELECT
[Project2].[Family] AS [Family],
[Project2].[C1] AS [C1],
[Project2].[Id] AS [Id],
[Project2].[Name] AS [Name],
[Project2].[Family1] AS [Family1],
[Project2].[Edible] AS [Edible],
CASE WHEN ([Project2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM (SELECT
[Distinct1].[Family] AS [Family],
1 AS [C1],
[Extent2].[Id] AS [Id],
[Extent2].[Name] AS [Name],
[Extent2].[Family] AS [Family1],
[Extent2].[Edible] AS [Edible]
FROM (SELECT DISTINCT
[Extent1].[Family] AS [Family]
FROM [dbo].[Fruits] AS [Extent1]) AS [Distinct1]
LEFT OUTER JOIN [dbo].[Fruits] AS [Extent2] ON ([Distinct1].[Family] = [Extent2].[Family]) OR (([Distinct1].[Family] IS NULL) AND ([Extent2].[Family] IS NULL))
) AS [Project2]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Fruits] AS [Extent3]
WHERE (([Project2].[Family] = [Extent3].[Family]) OR (([Project2].[Family] IS NULL) AND ([Extent3].[Family] IS NULL))) AND ([Extent3].[Edible] <> cast(1 as bit))
)
) AS [Project4]
ORDER BY [Project4].[Family] ASC, [Project4].[C2] ASC
但是下面的代碼裏面的謂詞是一個表達式:
Expression<Func<Fruit, bool>> innerPredicate = fruit => fruit.Edible;
var familiesWithAllEdibleFruits = context
.Fruits
.GroupBy(fruit => fruit.Family)
.Where(group => group.All(innerPredicate));
卡在編譯器的嗉囊:
「System.Linq.IGrouping <串,水果>」不包含「所有」的定義和最佳推廣方法重載「系統。 Linq.Enumerable.All < TSource>(System.Collections.Generic.IEnumerable < TSource>,System.Func < TSource,布爾>)」具有一些無效參數
然而當外謂詞是封裝在一個表達式中:
Expression<Func<IGrouping<string, Fruit>, bool>> outerPredicate =
group => group.All(fruit => fruit.Edible);
var familiesWithAllEdibleFruits = context
.Fruits
.GroupBy(fruit => fruit.Family)
.Where(outerPredicate);
事情工作正常。
我想了解我在這裏看到的更好的行爲。它看起來像在外部謂詞內對「全部」的調用將不允許表達式參數。是否可以使用Funcs和Expressions(如第二個例子)一樣方便地構成查詢,或者這是一個固有的限制嗎?
此問題可能與http://stackoverflow.com/questions/19930389/expression-tree-with-linq-expressions有關 – rtev 2014-09-12 20:24:44