简体   繁体   English

实体框架-根据子记录计算求和字段

[英]Entity framework - calculate sum field from child records

I'm using entity framework core with ASP.NET Core, code first. 我将实体框架核心与ASP.NET Core结合使用,首先进行编码。

In my app I have invoices, with the typical InvoiceHeader -> InvoiceLine relationship. 在我的应用程序中,我有具有典型InvoiceHeader > InvoiceLine关系的发票。 The InvoiceLine entities have a LineAmount field, which I want to sum and display on the InvoiceHeader when displayed as a list (so I can see the invoice total when viewing the list of invoices). InvoiceLine实体具有一个LineAmount字段,当我将InvoiceHeader显示为列表时,我想对其进行总计并显示在InvoiceHeader (这样,在查看发票列表时,我就可以看到发票总额)。

I'm guessing I'll need to add a TotalAmount property to the InvoiceHeader entity, with the annotation [NotMapped] . 我猜想我需要向InvoiceHeader实体添加一个TotalAmount属性,并带有注解[NotMapped] But how to most efficiently populate it? 但是如何最有效地填充它?

At the moment my InvoiceHeaderController.Index() is: 目前,我的InvoiceHeaderController.Index()是:

    // GET: InvoiceHeaders
    public async Task<IActionResult> Index()
    {
        ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
        var applicationDbContext = _context.InvoiceHeader.Include(i => i.Customer).Include(i => i.CustomerBranch)
            .Where(i => i.CustomerID == appUser.CustomerID);
        return View(await applicationDbContext.ToListAsync());
    }

Can anyone tell me what the most efficient way is to calculate (sum) this TotalAmount property? 谁能告诉我最有效的方法是计算(总和)此TotalAmount属性吗?

Thanks. 谢谢。

Selecting sum as separate field you need to create new model class as shown below 选择总和作为单独的字段,您需要创建新的模型类,如下所示

public class InvoiceHeaderModel{
   public InvoiceHeader invoiceHeader{get;set;}
   public decimal TotalAmount {get;set;}
}

and make change in action as 并改变行动

// GET: InvoiceHeaders
public async Task<IActionResult> Index()
{
    ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
    var applicationDbContext =await _context.InvoiceHeader.Where(i =>i.CustomerID == appUser.CustomerID).ToListAsync();
    var data = applicationDbContext.Aggregate( new List<InvoiceHeaderModel>(),(invoiceHeaderModellist, it)=>{ invoiceHeaderModellist.Add(new InvoiceHeaderModel(){ InvoiceHeader =it,TotalAmount  = it.InvoiceLine.Sum(t=>t.LineAmount)}); return invoiceHeaderModellist;});
    return View(data);
}

In this action i don't think you required to include 'Include(i => i.Customer).Include(i => i.CustomerBranch)' if required you can add before where closure. 在此操作中,我认为您不需要在需要关闭之前添加'Include(i => i.Customer).Include(i => i.CustomerBranch)'。

I managed to work it out. 我设法解决了。 Saneesh's suggestion was close, but not quite what I wanted. Saneesh的建议很接近,但并非我想要的。

The code I ended up using is: 我最终使用的代码是:

// GET: InvoiceHeaders

public async Task<IActionResult> Index()
{
    ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
            var applicationDbContext = _context.InvoiceHeader.Include(i => i.Customer).Include(i => i.CustomerBranch)
                .Where(i => i.CustomerID == appUser.CustomerID)
                .Select(i => new InvoiceListViewModel
                {
                    invoiceHeader = i,
                    TotalAmount = i.InvoiceLines.Sum(t => t.LineAmount)
                });
    return View(await applicationDbContext.ToListAsync());
}

Thanks for your help Saneesh. 感谢您的帮助,Saneesh。

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

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