簡體   English   中英

在 EF Core 7 中一起使用 union 和 select 時出現錯誤“無法在投影中轉換集合子查詢”

[英]Getting error 'Unable to translate a collection subquery in a projection' when using union and select together in EF Core 7

我編寫了一段代碼,EF Core 為其創建了一個表達式,如下所示:

DbSet<Reception>()
.Include(x => x.Employee)
.Include(x => x.ReceptionSignatures)
.Where(x => x.Employee.FirstName.Contains("mo"))
.Union(DbSet<Reception>()
    .Include(x => x.Employee)
    .Include(x => x.ReceptionSignatures)
    .Where(x => x.Employee.PersonelId.Contains("mo")))
.Union(DbSet<Reception>()
    .Include(x => x.Employee)
    .Include(x => x.ReceptionSignatures)
    .Where(x => x.Employee.LastName.Contains("mo")))
.Union(DbSet<Reception>()
    .Include(x => x.Employee)
    .Include(x => x.ReceptionSignatures)
    .Where(x => x.Employee.NationId.Contains("mo")))
.OrderBy(x => x.Employee.FirstName.CompareTo("mo") == 0 ? 0 : 1)
.Select(r => new ReceptionAllDTO{ 
    ReceptionId = r.Id, 
    NationId = r.Employee.NationId, 
    PersonelId = r.Employee.PersonelId, 
    FirstName = r.Employee.FirstName, 
    LastName = r.Employee.LastName, 
    Birthday = r.Employee.Birthday, 
    RecepDate = r.RecepDate, 
    Height = r.Height, 
    Weight = r.Weight, 
    ReceptionSignatures = r.ReceptionSignatures, 
}
)

Reception實體中,我與Signature有這樣的關系:

public virtual ICollection<Signature> ReceptionSignatures { get; set; }

但是當 EF Core 想要為 SQL 創建查詢時,它會拋出此異常:

無法在投影中轉換集合子查詢,因為父查詢或子查詢未投影唯一標識它並在客戶端正確生成結果所需的必要信息。 嘗試關聯無鍵實體類型時可能會發生這種情況。 對於“Distinct”之前的某些投影情況或“GroupBy”情況下分組鍵的某些形狀,也會發生這種情況。 這些應該包含應用操作的實體的所有關鍵屬性,或者只包含簡單的屬性訪問表達式。

看起來您正在查詢更多實際上效率不高的數據。 最好使用Select()投影所需的列,然后編寫Union

在編寫Union時,所選列的數量必須與我 2 周前編寫的代碼庫中顯示的相同,並且可以正常工作。

var billPaymentVoucherQuery = _context.Set<BillPaymentVoucher>().AsQueryable();
var billsQuery = _context.Set<Bill>().AsQueryable();
    
var anon_billsQuery = billsQuery.Where(w => w.InvoiceDate.Date <= filter.AsAtDate.Date)
                                            .Where(w => w.OperationalStatus == OperationalBillStatus.Approved &&
                                                        (
                                                          w.FinancialStatus == FinancialBillStatus.Pending ||
                                                          w.FinancialStatus == FinancialBillStatus.OnHold ||
                                                          w.FinancialStatus == FinancialBillStatus.PartiallyApproved ||
                                                          w.FinancialStatus == FinancialBillStatus.Approved
                                                        ))
                                            .Select(s => new
                                            {
                                                VendorName = s.VendorInvoice.Vendor!.Name,
                                                Type = "Bill",
                                                Date = s.InvoiceDate,
                                                Number = Convert.ToString(s.InvoiceNumber),
                                                Amount = s.LineItemTotal + s.VATAmount
                                            }).AsQueryable();
    
            var anon_billPaymentVoucherQuery = billPaymentVoucherQuery
                                              .Where(w => (
                                                           w.UpdatedOn.HasValue &&
                                                           w.UpdatedOn.Value.Date <= filter.AsAtDate.Date
                                                          )
                                                          ||
                                                          (
                                                           w.UpdatedOn.HasValue == false &&
                                                           w.CreatedOn.Date <= filter.AsAtDate.Date
                                                          ))
                                              .Where(w => w.BillPaymentVoucherStatus == BillPaymentVoucherStatus.Paid)
                                              .Select(s => new
                                              {
                                                  VendorName = s.PaymentApprovedBill.Bill.VendorInvoice.Vendor!.Name,
                                                  Type = "Payment",
                                                  Date = s.UpdatedOn ?? s.CreatedOn,
                                                  Number = Convert.ToString(s.PaymentApprovedBill.Bill.InvoiceNumber + " | " +
                                                                            s.PaymentVoucherNumber),
                                                  Amount = -s.PayAmount
                                              }).AsQueryable();
    
            var unionedQuery = anon_billsQuery.Union(anon_billPaymentVoucherQuery)
                                              .Where(w => string.IsNullOrWhiteSpace(filter.Type) || w.Type == filter.Type);
    
            int pageSize = 2;
            bool hasMoreRecords = true;
    
            
                var transactionData = await unionedQuery.OrderBy(w => w.VendorName)
                                                    .ThenBy(w => w.Date)
                                                    .Skip((paginator.PageNumber - 1) * pageSize)
                                                    .Take(pageSize)
                                                    .ToListAsync(token); 

暫無
暫無

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

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