ef核心:无法在包含聚合或子查询的表达式上执行汇总函数

问题描述 投票:0回答:1
I在EF6中有一个工作报告查询,由于我升级到Core 7.0.5,我会收到错误:

Cannot在包含聚合或子查询
的表达式上执行聚合函数

我有预订,每种都有多次付款尝试,我只想选择最新的付款尝试,然后总和所有这些付款金额。
var query = from reservation in DbContext.Reservations join p1 in DbContext.Payments on reservation.Id equals p1.ReservationId into p2 let payment = p2.OrderByDescending(x => x.Id).FirstOrDefault() orderby reservation.Id descending select new ReservationPaymentReport { ReservationId = reservation.Id, PaymentId = payment != null ? payment.Id : (int?)null, PaymentAmount = payment != null ? payment.Amount : (decimal?)null, IsPaymentCompleted = payment != null && paymentCompletedStatusIds.Contains(payment.StatusId), };

然后我使用该基本查询进行最终计算:
var paymentTotal = query
    .Where(x => x.PaymentId != null && x.IsPaymentCompleted.Value)
    .Sum(x => x.PaymentAmount) ?? 0;    

我应该在哪里进行重组/优化以使其正常工作?
update:

这是EF6生产的SQL,它使用

CROSS APPLY

正常工作。我已经清理了它并取代了可读性: SELECT SUM(Filter3.PaymentTotal) AS PaymentTotal FROM ( SELECT CASE WHEN p2.Id IS NOT NULL THEN p2.Amount END AS PaymentTotal FROM (SELECT Id FROM dbo.Reservations) AS r OUTER APPLY ( SELECT TOP 1 p1.Id, p1.Amount, p1.StatusId FROM ( SELECT p.Id, p.Amount, p.StatusId FROM dbo.Payments AS p WHERE r.Id = p.ReservationId ) AS p1 ORDER BY p1.Id DESC ) AS p2 WHERE ( CASE WHEN (p2.Id IS NOT NULL) THEN p2.Id END IS NOT NULL ) AND ( ( CASE WHEN (p2.Id IS NOT NULL AND p2.StatusId IN (6, 9, 7) AND p2.StatusId IS NOT NULL) THEN cast(1 as bit) WHEN ( NOT (p2.Id IS NOT NULL AND p2.StatusId IN (6, 9, 7) AND p2.StatusId IS NOT NULL)) THEN cast(0 as bit) END ) = 1 ) ) AS Filter3

这是EF Core 7.0.5:

产生的清理SQL
SELECT COALESCE 
(
    SUM((
    SELECT TOP 1 p2.Amount
    FROM Payments AS p2
    WHERE r.Id = p2.ReservationId
    ORDER BY p2.Id DESC)), 0.0
)
FROM Reservations AS r
WHERE
    ((
        SELECT TOP 1 p.Id
        FROM Payments AS p
        WHERE r.Id = p.ReservationId
        ORDER BY p.Id DESC
    ) IS NOT NULL)
    AND EXISTS
    (
        SELECT 1
        FROM Payments AS p0
        WHERE r.Id = p0.ReservationId
    )
    AND
    (
        SELECT TOP 1 p1.StatusId
        FROM Payments AS p1
        WHERE r.Id = p1.ReservationId
        ORDER BY p1.Id DESC
    ) IN (6, 9, 7)

这是EF Core 8及以下的已知缺失功能,现在已经通过EF 9进行了支持。
Github上的门票跟踪了该功能的开发:
https://github.com/dotnet/efcore/issues/34256
entity-framework-core
1个回答
0
投票

这是发布公告:

https://learn.microsoft.com/en-us/core/what-is-new/ef-core-9.0/whatsnew#simenficastifal--imprastificational-linq-querying-capabilitions

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.