简体   繁体   English

实体框架从子属性中获取 SUM

[英]Entity Framework get SUM from child property

I have the following model where I'd like to get the sum of all OrderTotalItems for all Orders of a Customer where the OrderTotalType (Enumeration) is "total" or 99:我有以下 model ,我想在其中获取 OrderTotalType (枚举)为“总计”或 99 的客户的所有订单的所有 OrderTotalItems 的总和:

public class Customer
{
    ...
    public ICollection<Order> Orders { get; set; } = new Collection<Order>();
}

public class Order
{
    ...
    public ICollection<OrderTotalItem> OrderTotalItems { get; set; } = new Collection<OrderTotalItem>();
}

public class OrderTotalItem
{
    [Required]
    public int Id { get; set; }
    [Required]
    [Column(TypeName = "decimal(10, 4)")]
    public decimal Value { get; set; }
    [Required]
    public OrderTotalType Type { get; set; }
}

I am building a CustomerAdminDTO to include all relevant data of a customer for the admin client:我正在构建一个 CustomerAdminDTO 以包含管理客户端的客户的所有相关数据:

public class CustomerAdminDto
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public Gender Gender { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string VATId { get; set; } = "";
    public bool VATIdValid { get; set; } = false;
    public DateTime Added { get; set; }
    public DateTime LastModified { get; set; }
    public decimal OrdersTotal { get; set; }
    public CustomerStatusShortDto CustomerStatus { get; set; }
    public CustomerAddressDto CustomerAddress { get; set; }
    public CustomerAddressDto BillingAddress { get; set; }
    public ICollection<OrderListShortDto> Orders { get; set; }
}

In my data service I fill the DTO like that在我的数据服务中,我像这样填写 DTO

var customerAdmin = await _context.Customers
    .Include(x => x.Addresses)
    .Include(x => x.CustomerStatus)
    .Include(x => x.Orders)
        .ThenInclude(x => x.OrderTotalItems)
    .Where(x => x.UserId == userid)
    .Select(customer => new CustomerAdminDto 
    {
        Id = customer.Id,
        UserId = customer.UserId,
        Gender = customer.Gender,
        FirstName = customer.FirstName,
        LastName = customer.LastName,
        VATId = customer.VATId,
        VATIdValid = customer.VATIdValid,
        Added = customer.Added,
        LastModified = customer.LastModified,
        OrdersTotal = customer.Orders.Sum(x => x.OrderTotalItems
            .Where(x => x.Type == Enums.OrderTotalType.Total)
            .Sum(x => x.Value)),
        CustomerStatus = new CustomerStatusShortDto
        {
            Id = customer.CustomerStatus.Id,
            Name = customer.CustomerStatus.Name,
        },
    ...
    }
    .FirstOrDefaultAsync();

where everything works, except the OrdersTotal.一切正常的地方,除了 OrdersTotal。

API compiles fine but throws the following error at runtime: API 编译正常,但在运行时抛出以下错误:

Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot perform an aggregate function on an expression containing an aggregate or a subquery. Microsoft.Data.SqlClient.SqlException (0x80131904):无法对包含聚合或子查询的表达式执行聚合 function。

Thanks for your hints!感谢您的提示!

Cannot perform an aggregate function on an expression containing an aggregate or a subquery.无法对包含聚合或子查询的表达式执行聚合 function。

This error in SQL server means that you tried to call aggregation function ( customer.Orders.Sum() in your case) on other expression that contains aggregation function ( .Sum(x => x.Value) in your case). This error in SQL server means that you tried to call aggregation function ( customer.Orders.Sum() in your case) on other expression that contains aggregation function ( .Sum(x => x.Value) in your case). In order to avoid this you can simplify your LINQ expression for OrdersTotal :为了避免这种情况,您可以简化OrdersTotal的 LINQ 表达式:

OrdersTotal = customer.Orders.SelectMany(o => o.OrderTotalItems).Where(x => x.Type == Enums.OrderTotalType.Total).Sum(x => x.Value)

There is only one aggregation here so it should work fine这里只有一个聚合,所以它应该可以正常工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM