我有以下类(class)
public class Order
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime Date { get; set; }
public decimal TotalPaid { get { return Payments.Sum(x => x.Amount); } }
public decimal Total { get { return OrderItems.Sum(x => x.TotalPrice); } }
public bool PaidCompletely { get { return Total == TotalPaid; } }
public List<OrderItem> OrderItems { get; set; } = new List<OrderItem>();
public List<Payment> Payments { get; set; } = new List<Payment>();
}
public class OrderItem
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public decimal PricePerUnit { get; set; }
public decimal Quantity { get; set; }
public decimal TotalPrice { get { return PricePerUnit * Quantity; } }
}
public class Payment
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public decimal Amount { get; set; }
public DateTime Date { get; set; }
}
我想获得所有未全额支付的订单。
以下是无效的
var OrdersNotFullyPaidShort =
context
.Orders
.Where(order => !order.PaidCompletely)
.ToList();
报错
The LINQ expression 'Where(source: DbSet, predicate: (o) => !(o.PaidCompletely))' could not be translated...
以下工作正常,但我必须在查询中再次重写所有逻辑,同时我还在类中定义了逻辑:
var OrdersNotFullyPaidLong =
context
.Orders
.Where(order => order.OrderItems.Sum(orderItem => orderItem.PricePerUnit * orderItem.Quantity) == order.Payments.Sum(payment => payment.Amount))
.ToList();
并生成这个非常难看的查询:
SELECT [o].[Id], [o].[Date]
FROM [Orders] AS [o]
WHERE (((
SELECT SUM([o0].[PricePerUnit] * [o0].[Quantity])
FROM [OrderItems] AS [o0]
WHERE ([o].[Id] = [o0].[OrderId]) AND [o0].[OrderId] IS NOT NULL) = (
SELECT SUM([p].[Amount])
FROM [Payments] AS [p]
WHERE ([o].[Id] = [p].[OrderId]) AND [p].[OrderId] IS NOT NULL)) AND ((
SELECT SUM([o0].[PricePerUnit] * [o0].[Quantity])
FROM [OrderItems] AS [o0]
WHERE ([o].[Id] = [o0].[OrderId]) AND [o0].[OrderId] IS NOT NULL) IS NOT NULL AND (
SELECT SUM([p].[Amount])
FROM [Payments] AS [p]
WHERE ([o].[Id] = [p].[OrderId]) AND [p].[OrderId] IS NOT NULL) IS NOT NULL)) OR ((
SELECT SUM([o0].[PricePerUnit] * [o0].[Quantity])
FROM [OrderItems] AS [o0]
WHERE ([o].[Id] = [o0].[OrderId]) AND [o0].[OrderId] IS NOT NULL) IS NULL AND (
SELECT SUM([p].[Amount])
FROM [Payments] AS [p]
WHERE ([o].[Id] = [p].[OrderId]) AND [p].[OrderId] IS NOT NULL) IS NULL)
没有办法用我第一种查询方式吗?我做错了什么,我的类(class)没有明确定义吗?
最佳答案
我已经试过了:
var query = db.Order.Select(x => new { Id = x.Id, Date = x.Date,
Payments = x.Payments.Sum(y => y.Amount),
ToPay = x.OrderItems.Sum(y => y.PricePerUnit * y.Quantity)})
.Where(x => x.Payments < x.ToPay);
它创造了
SELECT
[Project2].[Id] AS [Id],
[Project2].[Date] AS [Date],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[Date] AS [Date],
[Project1].[C1] AS [C1],
(SELECT
SUM([Filter2].[A1_0]) AS [A1]
FROM ( SELECT
[Extent3].[PricePerUnit] * [Extent3].[Quantity] AS [A1_0]
FROM [dbo].[OrderItems] AS [Extent3]
WHERE [Project1].[Id] = [Extent3].[Order_Id]
) AS [Filter2]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Date] AS [Date],
(SELECT
SUM([Extent2].[Amount]) AS [A1]
FROM [dbo].[Payments] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[Order_Id]) AS [C1]
FROM [dbo].[Orders] AS [Extent1]
) AS [Project1]
) AS [Project2]
WHERE ([Project2].[C1] < [Project2].[C2]) AND ([Project2].[C1] < [Project2].[C2])
对我来说看起来很安静 这可能取决于 LINQ 提供程序,以及创建的查询。
在关心“丑陋”的查询之前,您应该庆幸可以创建一个有效的查询。 进一步优化 LINQ 表达式的唯一原因是性能。 您无法针对可读性或美观进行优化。
关于c# - 根据子集合总和的比较执行单个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58462412/