C# 实体框架-从子记录计算总和字段
我使用的是实体框架核心和ASP.NET核心,代码优先 在我的应用程序中,我有发票,具有典型的C# 实体框架-从子记录计算总和字段,c#,asp.net,asp.net-mvc,entity-framework,entity-framework-core,C#,Asp.net,Asp.net Mvc,Entity Framework,Entity Framework Core,我使用的是实体框架核心和ASP.NET核心,代码优先 在我的应用程序中,我有发票,具有典型的InvoiceHeader->InvoiceLine关系。InvoiceLine实体有一个LineAmount字段,当显示为列表时,我希望将其相加并显示在InvoiceHeader上(这样我可以在查看发票列表时看到发票总额) 我猜我需要在InvoiceHeader实体中添加一个TotalAmount属性,带有注释[NotMapped]。但是如何最有效地填充它呢 目前我的InvoiceHeaderContr
InvoiceHeader
->InvoiceLine
关系。InvoiceLine
实体有一个LineAmount
字段,当显示为列表时,我希望将其相加并显示在InvoiceHeader
上(这样我可以在查看发票列表时看到发票总额)
我猜我需要在InvoiceHeader
实体中添加一个TotalAmount
属性,带有注释[NotMapped]
。但是如何最有效地填充它呢
目前我的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());
}
//获取:InvoiceHeaders
公共异步任务索引()
{
ApplicationUser appUser=ConstantData.GetApplicationUser(_context,_userManager.GetUserId(User));
var applicationDbContext=\u context.InvoiceHeader.Include(i=>i.Customer).Include(i=>i.CustomerBranch)
.Where(i=>i.CustomerID==appUser.CustomerID);
返回视图(等待applicationDbContext.toListSync());
}
有谁能告诉我计算(和)这个TotalAmount
属性最有效的方法是什么
谢谢。选择sum作为单独字段,您需要创建新的模型类,如下所示
public class InvoiceHeaderModel{
public InvoiceHeader invoiceHeader{get;set;}
public decimal TotalAmount {get;set;}
}
并在行动上做出改变
// 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);
}
//获取:InvoiceHeaders
公共异步任务索引()
{
ApplicationUser appUser=ConstantData.GetApplicationUser(_context,_userManager.GetUserId(User));
var applicationDbContext=await _context.InvoiceHeader.Where(i=>i.CustomerID==appUser.CustomerID.toListSync();
var data=applicationDbContext.Aggregate(new List(),(invoiceHeaderModellist,it)=>{invoiceHeaderModellist.Add(new InvoiceHeaderModel(){InvoiceHeader=it,TotalAmount=it.InvoiceLine.Sum(t=>t.LineAmount)});返回invoiceHeaderModellist;});
返回视图(数据);
}
在这个操作中,我认为您不需要包括“include(i=>i.Customer)。include(i=>i.CustomerBranch)”,如果需要,您可以在where closure之前添加。选择sum作为单独的字段,您需要创建新的模型类,如下所示
public class InvoiceHeaderModel{
public InvoiceHeader invoiceHeader{get;set;}
public decimal TotalAmount {get;set;}
}
并在行动上做出改变
// 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);
}
//获取:InvoiceHeaders
公共异步任务索引()
{
ApplicationUser appUser=ConstantData.GetApplicationUser(_context,_userManager.GetUserId(User));
var applicationDbContext=await _context.InvoiceHeader.Where(i=>i.CustomerID==appUser.CustomerID.toListSync();
var data=applicationDbContext.Aggregate(new List(),(invoiceHeaderModellist,it)=>{invoiceHeaderModellist.Add(new InvoiceHeaderModel(){InvoiceHeader=it,TotalAmount=it.InvoiceLine.Sum(t=>t.LineAmount)});返回invoiceHeaderModellist;});
返回视图(数据);
}
在这个操作中,我认为您不需要包括“include(i=>i.Customer).include(i=>i.CustomerBranch)”,如果需要,您可以在where closure之前添加。我设法解决了这个问题。萨尼什的建议很接近,但不是我想要的 我最终使用的代码是:
// 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());
}
//获取:InvoiceHeaders
公共异步任务索引()
{
ApplicationUser appUser=ConstantData.GetApplicationUser(_context,_userManager.GetUserId(User));
var applicationDbContext=\u context.InvoiceHeader.Include(i=>i.Customer).Include(i=>i.CustomerBranch)
.Where(i=>i.CustomerID==appUser.CustomerID)
.选择(i=>new InvoiceListViewModel
{
invoiceHeader=i,
TotalAmount=i.InvoiceLines.Sum(t=>t.LineAmount)
});
返回视图(等待applicationDbContext.toListSync());
}
谢谢你的帮助,萨尼什。我设法解决了。萨尼什的建议很接近,但不是我想要的 我最终使用的代码是:
// 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());
}
//获取:InvoiceHeaders
公共异步任务索引()
{
ApplicationUser appUser=ConstantData.GetApplicationUser(_context,_userManager.GetUserId(User));
var applicationDbContext=\u context.InvoiceHeader.Include(i=>i.Customer).Include(i=>i.CustomerBranch)
.Where(i=>i.CustomerID==appUser.CustomerID)
.选择(i=>new InvoiceListViewModel
{
invoiceHeader=i,
TotalAmount=i.InvoiceLines.Sum(t=>t.LineAmount)
});
返回视图(等待applicationDbContext.toListSync());
}
感谢您的帮助,Saneesh。您的数据模型不应包含该属性。对其使用视图模型。您只需使用linq
.Sum()
即可获得总额。您在InvoiceLine中有行金额字段,并且InvoiceHeader中已经有一个CustomerID字段。您必须在Invoiceheader控制器中按客户填写行金额的总和,对吗?@StephenMuecke:实际上,这取决于具体情况。有时,预先计算总金额并将其存储在“标题”中是很有用的—当您不需要详细信息时,检索速度更快。有时,这可用于验证数据完整性(某种审计)。当然,这也有它自己的缺点。@Saneeshkunjunni:CustomerID在这里并不重要。这只是这张发票的客户ID。一个客户可以有多张发票,在这种情况下,一个客户的每张发票都有不同的发票total@StephenMuecke:谢谢。我试试看。你的数据模型不应该包含那个属性。对其使用视图模型。您只需使用linq.Sum()
即可获得总额。您在InvoiceLine中有行金额字段,并且InvoiceHeader中已经有一个CustomerID字段。您必须在Invoiceheader控制器中按客户填写行金额的总和,对吗?@StephenMuecke:实际上,这取决于具体情况。有时,预先计算总金额并将其存储在“标题”中是很有用的—当您不需要详细信息时,检索速度更快。有时这可能