鑑於兩類生成的代碼先用EF,具有父子關係:屬性總和轉換爲對IQueryable的SQL和LINQ到實體
class Parent {
//...
public virtual ICollection<Child> Children
}
class Child {
//...
public decimal Amount{ get; set; }
public decimal UnitPrice { get; set; }
}
我想對家長創建一個屬性Total
,像
但如果我這樣做那樣,然後做
var list = ctx.Parents
.Where(p => p.Total > 1000)
.Select(p => new {
p.Id,
p.Total,
Count = p.Children.Count });
foreach(var item in list){
Console.WriteLine($"Id: {item.} ...");
}
我,說
「System.NotSupportedException」類型的未處理的異常出現在EntityFramework.SqlServer.dll
錯誤其他信息:指定的類型成員「合計」不支持LINQ到實體。僅支持初始化程序,實體成員和實體導航屬性。
雖然,在我看來,它不應該那麼難EF生成查詢使用SUM(UnitPrice * Amount) as Total
我無法得到它的工作。
我已經用靜態表達試過像
public static Expression<Func<Parent, decimal>> GetTotal()
{
return p=> p.Children.Sum(line => line.ItemQty * line.UnitPrice);
}
雖然它應該是可以接受做這個計算只是代碼。我想用這個例子來學習更多關於如何使用IQueryable的知識。
一個小更迭
鑑於家長
public static Expression<Func<Parent, decimal?>> Total =>
p=> (from c in p.Childeren
select c.UnitPrice * c.ItemQty).Sum();
而下面的靜態屬性然後做
var list = ctx.Parents.Select(Parent.Total);
我得到了一個包含所有彙總列表,我看到了EF生成以下查詢
SELECT (SELECT SUM([Filter1].[A1]) AS [A1] FROM (SELECT [Extent2].[UnitPrice] * CAST([Extent2].[Amount] AS decimal(19,0)) AS [A1] FROM [dbo].[Child] AS [Extent2] WHERE [Extent1].[Id] = [Extent2].[ParentId] ) AS [Filter1]) AS [C1] FROM [dbo].[Parent] AS [Extent1]
因此,它確實能夠將Sum()方法轉換爲SQL。現在我只需要在Where()中使用它。
感謝您的解釋。我們確實正在解決性能問題(比此更復雜的場景),其中EF需要長達9秒,而手工查詢在300ms內完成。我正在調查EF的功能,因爲我不想回過頭來手動編寫SQL查詢並在數據庫中複製業務邏輯。 –
@StijnVanAntwerpen EF是一個附加層。充其量,與手工製作SQL查詢相比,您將獲得相同的性能(或性能可以忽略不計)。 EF受限於它可以隱式地從C#轉換爲SQL。 – Flater
嗯,我知道EF有限制將c#翻譯成sql(當然,它仍然不使用魔法)。我希望像Sum()這樣的東西得到支持......如果我確實在DB(VW_ParentWithTotal)中定義了一個視圖讓EF從中生成模型,那麼開銷是可以忽略的。但我正試圖消除這一步。 (因爲VW_ParentWithTotal已經存在於c#中的BL) –