【发布时间】:2022-11-02 20:50:25
【问题描述】:
我正在使用 EFCore 在 C# 中编写应用程序。
我有实体Customer、Order、OrderItem 和Product。
OrderItem 是一个关联表,将Order 与Product 连接起来,因此一个订单可以有多个产品。
Order 包含对客户的引用。
OrderItem 包含对 Product 和 Order 的引用。
通过引用,我的意思是外键约束。
问题是当我尝试执行以下方法时,出现以下错误:
public static List<SalesStatistic> GetInvoices()
{
using ApplicationDbContext context = new ApplicationDbContext();
return context.Customers.Select(c => new SalesStatistic()
{
FirstName = c.FirstName,
LastName = c.LastName,
TotalPrice = context.Orders.Where(o => o.CustomerId == c.Id).Sum(oo => GetSalesPerOrder(oo.Nr))
}).ToList();
}
System.InvalidOperationException: The LINQ expression 'DbSet<Order>()
.Where(o => o.CustomerId == EntityShaperExpression:
Core.Entities.Customer
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
.Id)
.Sum(o => Repository.GetSalesPerOrder(o.Nr))' could not be translated. Additional information: Translation of method 'Persistence.Repository.GetSalesPerOrder' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
GetSalesPerOrder 方法的工作原理是我为这些方法设置了单元测试。
public static double GetSalesPerOrder(string orderNr)
{
using ApplicationDbContext context = new ApplicationDbContext();
return context.Orders.Include(o => o.OrderItems).Where(o => o.Nr == orderNr).First().OrderItems!.Sum(oi => context.OrderItems.Include(o => o.Product).Where(oii => oii.Id == oi.Id).First().Product.Price * oi.Amount);
}
我试图修改GetInvoices,所以它不会调用GetSalesPerOrder,然后没有抛出异常。
我想知道我在上面的代码中做错了什么。
【问题讨论】:
-
GetSalesPerOrder(oo.Nr)是一种方法。 EF 正在尝试将其转换为 SQL 查询,但它不知道如何处理该方法,因为它无法转换为 SQL。