我正在使用EF Core 2.1,并且查询在SQL Server端不进行评估。
此查询中使用的模型为:
public class V_TurnoverByDivision
{
public long Id { get; set; }
public decimal LineAmount { get; set; }
public DateTime? PostingDate { get; set; }
public decimal Quantity { get; set; }
public decimal UnitCostLcy { get; set; }
public string DivisionCode { get; set; }
public string DivisionDescription { get; set; }
public string TopDivisionCode { get; set; }
public string TopDivisionDescription { get; set; }
public decimal RUCAmount { get; set; }
}
此LINQ语句在SQL Server中完全运行:
return query
.GroupBy(g => new { g.DivisionCode, g.DivisionDescription, g.TopDivisionCode, g.TopDivisionDescription, g.PostingDate })
.Select(s =>
new V_TurnoverByDivision
{
DivisionCode = s.Key.DivisionCode,
DivisionDescription = s.Key.DivisionDescription,
TopDivisionCode = s.Key.TopDivisionCode,
TopDivisionDescription = s.Key.TopDivisionDescription,
PostingDate = s.Key.PostingDate,
LineAmount = s.Sum(ss => ss.LineAmount),
RUCAmount = s.Sum(ss => ss.LineAmount - (ss.Quantity * ss.UnitCostLcy))
});
并生成以下SQL
选择 [v]。[BIInvCNLinesID] ,[v]。[DivisionCode] ,[v]。[DivisionDescription] ,[v]。[LineAmount] ,[v]。[PostingDate] ,[v]。[数量] ,[v]。[TopDivisionCode] ,[v]。[TopDivisionDescription] ,[v]。[UnitCostLcy] 从[V_TurnoverByDivision] AS [v] 在[v]。[PostingDate]> = @__ firstDayOfcurrentMonth_0 ORDER BY [v]。[DivisionCode],[v]。[DivisionDescription],[v]。[TopDivisionCode],[v]。[TopDivisionDescription],[v]。[PostingDate]
此LINQ语句有效,但在内存中执行GroupBy
在“输出”窗口中出现警告
Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式'Sum()'无法翻译,将在本地进行评估。
但我何时使用此查询
return query
.GroupBy(g => new { g.DivisionCode, g.DivisionDescription, g.TopDivisionCode, g.TopDivisionDescription, g.PostingDate })
.Select(s =>
new V_TurnoverByDivision
{
DivisionCode = s.Key.DivisionCode,
DivisionDescription = s.Key.DivisionDescription,
TopDivisionCode = s.Key.TopDivisionCode,
TopDivisionDescription = s.Key.TopDivisionDescription,
PostingDate = s.Key.PostingDate,
LineAmount = s.Sum(ss => ss.LineAmount)
});
};
,SQL生成的查询应为:
选择 [v]。[DivisionCode] ,[v]。[DivisionDescription] ,[v]。[TopDivisionCode] ,[v]。[TopDivisionDescription] ,[v]。[PostingDate] ,SUM([v]。[LineAmount])AS [LineAmount] 从[V_TurnoverByDivision] AS [v] 在[v]。[PostingDate]> = @__ firstDayOfcurrentMonth_0 GROUP BY [v]。[DivisionCode] ,[v]。[DivisionDescription] ,[v]。[TopDivisionCode] ,[v]。[TopDivisionDescription] ,[v]。[PostingDate]
如何解决问题宽度
RUCAmount = s.Sum(ss => ss.LineAmount-(ss.Quantity * ss.UnitCostLcy))
答案 0 :(得分:2)
这是EF Core GroupBy
的翻译限制(可能会在将来的某些版本中解决)。为了能够转换为SQL,聚合方法表达式应该是简单的属性访问器。
这就是为什么
s.Sum(ss => ss.LineAmount)
翻译,但是
s.Sum(ss => ss.LineAmount - (ss.Quantity * ss.UnitCostLcy))
没有。
因此,解决方案是预先选择聚合所需的表达式。一种方法是对元素选择器使用GroupBy重载:
return query
.GroupBy(e => new // Key
{
e.DivisionCode,
e.DivisionDescription,
e.TopDivisionCode,
e.TopDivisionDescription,
e.PostingDate
},
e => new // Element
{
e.LineAmount,
RUCAmount = e.LineAmount - (e.Quantity * e.UnitCostLcy) // <--
})
.Select(g => new V_TurnoverByDivision
{
DivisionCode = g.Key.DivisionCode,
DivisionDescription = g.Key.DivisionDescription,
TopDivisionCode = g.Key.TopDivisionCode,
TopDivisionDescription = g.Key.TopDivisionDescription,
PostingDate = g.Key.PostingDate,
LineAmount = g.Sum(e => e.LineAmount),
RUCAmount = g.Sum(e => e.RUCAmount) // <--
});