0

私はエンティティフレームワークのコアをASP.NETコアで使用しています。エンティティフレームワーク - 子レコードから合計フィールドを計算する

私のアプリでは、典型的なInvoiceHeader - >InvoiceLineという関係の請求書があります。 InvoiceLineエンティティはLineAmountフィールドを持っています。これを合計してInvoiceHeaderに表示すると、リストとして表示されます(請求書の一覧を表示する際に請求書の合計が表示されます)。

私は、[NotMapped]InvoiceHeaderエンティティにTotalAmountプロパティを追加する必要があると推測しています。しかし、それを最も効率的に埋める方法は?

瞬間に私の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()); 
    } 

誰もが最も効率的な方法は、(合計)このTotalAmountプロパティを計算することが何であるかを教えてもらえますか?

ありがとうございました。

私はあなたがする必要はないと思う。このアクションで

// 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); 
} 

としてあなたが

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

以下のように新しいモデルクラスを作成し、行動に変化を加える必要がある別のフィールドとして合計を選択

+1

データモデルにはそのプロパティが含まれていてはなりません。ビューモデルを使用します。そして、あなたはlinq '.Sum()'を使って合計を得ることができます。 –

+0

InvoiceLineにLine Amountフィールドがあり、すでにInvoiceHeaderに1つのCustomerIDフィールドがあります。あなたはInvoiceheaderのコントローラの顧客ごとにLineの金額の合計を入力する必要がありますか? –

+0

@StephenMuecke:実際、それは依存しています。場合によっては、合計金額を事前に計算して「ヘッダー」に保存すると便利なことがあります。詳細が必要ない場合は、検索するだけで簡単です。場合によっては、これを使用してデータの整合性(ある種の監査)を検証することができます。もちろん、これには独自の短所があります。 – Dennis

答えて

0

'Include(i => i.Customer).Include(i => i.CustomerBranch)'を必要に応じて追加することができます。

+0

ありがとうございます。私はこれを試してみる。 – Shaggs

+0

この問題を解決するには問題があります。 1つのオブジェクトをリストにすることはできないため、applicationDbContextにコードを埋め込む行には、1つのInvoiceHeaderModel(リストの種類ではない)が設定されているように見えるので、ToListAsync()メソッドはコンパイルされません。 – Shaggs

+0

こんにちは@Shaggs私はInvoiceHeaderModelのリストを編集してこれを試してください。 –

0

私はそれを解決することができました。 Saneeshの提案は近いが、私が望んでいたものではない。

私が使用して終了コードは次のとおりです。あなたの助けSaneeshため

// 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()); 
} 

感謝。

関連する問題