簡體   English   中英

我的 Linq 查詢是否在 EF Core 3.1 中具有最佳和高性能?

[英]Is my Linq Query Optimal and High performance in EF Core 3.1?

我可以刪除 vg.First().Voucher 嗎? 並替換更好的代碼? 什么是最佳和最佳實踐? 可以將此代碼轉換為另一種方法嗎? 像鏈式方法?

        var query = from v in _journalLineRepository.TableNoTracking
                .Include(j => j.Voucher).AsEnumerable()
                    group v by v.AccountId into vg
                    select new // <-- temporary projection with group by fields needed
                    {
                        AccountId = vg.Key,
                        Credit = vg.Sum(v => v.Credit),
                        Debit = vg.Sum(v => v.Debit),
                        Voucher = vg.First().Voucher

                    } into vg
                    join p in _partyRepository.TableNoTracking.Include(p => p.PartyPhones).AsEnumerable() on vg.AccountId equals p.AccountId // <-- additional join(s)
                    select new PartyDeptorAndCreditorViewModel
                    {



                        PartyId = p.Id,
                        FullName = p.FullName,
                        PhoneNo = p.PartyPhones.FirstOrDefault(p => p.IsActive)?.Phone,
                        ProjectId = vg.Voucher.ProjectId,
                        AccountId = vg.AccountId.Value,
                        Creditor = vg.Credit,
                        Deptor = vg.Debit,
                        Balance = vg.Credit - vg.Debit,
                        VoucherDate = vg.Voucher.VoucherDate,
                        VoucherRegisterDate = vg.Voucher.VoucherDate,
                        BalanceType =
                            vg.Debit > vg.Credit ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name) :
                            vg.Debit < vg.Credit ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name) :
                             AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name),

                    };

我肯定會查看生成的 SQL 查詢。 從表面上看,我看到一些警告標志,它可能不是在編寫查詢,而是可能預先執行到內存中的處理,這將是低效的。 它首先取決於這些.TableNoTracking方法/屬性返回什么,以及在急切加載連接上使用.AsEnumerable

首先,使用Select進行投影時,不需要急切加載連接( .Include )。 投影將為您處理連接,只要它向下投影到 SQL。 如果您取出.Include().AsEnumerable()調用並且您的查詢仍然有效,那么它可能會投射到 SQL。 如果它不再工作,那么它在 memory 中處理並且效率不高。

編輯:不,內部投影無法解決: 關於 .Voucher ,您的最終投影使用該實體的 2 個字段,因此您可以在初始投影中替換它:

 select new // <-- temporary projection with group by fields needed { AccountId = vg.Key, Credit = vg.Sum(v => v.Credit), Debit = vg.Sum(v => v.Debit), Voucher = vg.Select(v => new { v.ProjectId, v.VoucherDate }).First() } into vg

當涉及到這樣的轉換時:

BalanceType = vg.Debit > vg.Credit 
    ?        AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name) 
    : vg.Debit < vg.Credit 
        ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name) 
        : AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name),

...在一個投影中,這會發出警告標志,因為 Linq2EF 需要將投影組合到 SQL 因此無法理解像ToDisplay這樣的方法/擴展。 相反,由於這僅基於貸方/借方金額,因此我將其移動到由視圖 model 中的屬性計算:

select new PartyDeptorAndCreditorViewModel
{
    PartyId = p.Id,
    FullName = p.FullName,
    PhoneNo = p.PartyPhones
        .Where(p => p.IsActive)
        .Select(p => p.Phone)
        .FirstOrDefault(),
    ProjectId = vg.Voucher.ProjectId,
    AccountId = vg.AccountId.Value,
    Creditor = vg.Credit,
    Deptor = vg.Debit,
    Balance = vg.Credit - vg.Debit,
    VoucherDate = vg.Voucher.VoucherDate,
    VoucherRegisterDate = vg.Voucher.VoucherDate
};

然后在model視圖中:

[Serializable]
public class PartyDebtorAndCreditorViewModel
{
    // ... 
    public decimal Balance { get; set; }

    public string BalanceType 
    {
        get 
        { 
             return Balance < 0 
                ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name) 
                : Balance > 0
                    ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name) 
                    : AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name);
        }
    }
}

暫無
暫無

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

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