簡體   English   中英

在 EfCore 的相關模型中通過 Sum 聚合有效地查詢/排序

[英]Efficiently querying/ordering by Sum aggregate in related model in EfCore

我對 C#、.NET 和 EfCore 還很陌生,所以如果我在問題中遺漏了什么,請多多包涵並道歉。

假設我有以下關系

public class User
{
    public Account Account {get; set;}
    public string Foo {get; set;}

}

public class Account
{
    public List<Transaction> Transactions {get; set;}
}

public class Transaction
{
    public decimal Amount {get; set;}
    public TransactionType TransactionType {get; set;}

}

public enum TransactionType 
{
    Credit = 1,
    Debit = 2,
    Refund = 3,
}

我想使用余額,每次檢索用戶模型時都需要計算余額。 對於這個例子,假設我需要按用戶的帳戶余額排序一個用戶列表,其中 Foo 是“Bar”

var query = db.Users
    .Include(u => u.Account)
    .ThenInclude(a => a.Transactions)
    .Where(u => u.Foo == "Bar");

var orderedQuery = query
         .OrderByDescending(u => 
              (u.Account.Transactions
                .Where(t => t.TransactionType == TransactionType.Credit || t.TransactionType == TransactionType.Refund)
                .Sum(t => t.Amount)) 
              - u.Account.Transactions
                 .Where(t => t.TransactionType == TransactionType.Debit)
                 .Sum(t => t.Amount)
              )
);


// Build the List
return orderedQuery.Skip(...).Take(...).Select(x => new SomeDTO{/* Build some DTO's with User Info, Account Info and Balance */}).ToList();

上述工作,但效率低下。

我正在一個 asp.net 核心和 sql-server 項目中處理一個相當大的代碼庫和現有數據庫,所以我需要使用我所擁有的。 任何人都可以建議一種更好的方式來完成這種工作嗎?

你真的需要所有這些Include嗎? 以后的排序聚合不需要它們。

var query = db.Users
    .Include(u => u.Account)
    .ThenInclude(a => a.Transactions)
    .Where(u => u.Foo == "Bar");

您可以通過組合成一個分組來優化查詢的排序部分

var orderedQuery = query.OrderByDescending(u =>
    u.Account.Transactions
    .GroupBy(t => 1)
    .Select(g =>
          g.Where(t => t.TransactionType == TransactionType.Credit || t.TransactionType == TransactionType.Refund)
           .Sum(t => t.Amount)
        - g.Where(t => t.TransactionType == TransactionType.Debit)
           .Sum(t => t.Amount)
        )
    );

Skip Take效率很低,因為它需要再次搜索整個列表。 謹慎的做法是將其全部緩存在客戶端中,然后再對其進行分頁。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM