I am writing an application in C# using EFCore.
I have the Entities Customer
, Order
, OrderItem
and Product
.
OrderItem
is a associative table connecting Order
with Product
so an order can have multiple products.
Order
contains a reference to customer.
OrderItem
contains a reference to Product
and Order
.
By reference I mean a foreign-key constraint.
The problem is that when I try to execute the following method, I get the following error:
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.
The method GetSalesPerOrder
works as I have Unit-Tests set up for these methods.
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);
}
I tried to modify GetInvoices
so it doesn't call GetSalesPerOrder
and then no exception was thrown.
I want to know what I am doing wrong in the above code.