我正在從物件串列構建自定義模型,我使用的代碼如下所示
var dataset = await query.Select(c => new ContactListModel
{
Id = c.Id,
FirstName = c.FirstName,
LastName = c.LastName,
Email = c.Email,
EmailAlternative = c.EmailAlternative,
JobTitle = c.JobTitle,
CompanyName = (c.Company != null) ? c.Company.Name : "",
AddressCountry = c.Addresses.FirstOrDefault(a=>a.IsPrimary) != null ? c.Addresses.FirstOrDefault(a => a.IsPrimary).Country.Name : "",
AddressCounty = c.Addresses.FirstOrDefault(a => a.IsPrimary) != null ? c.Addresses.FirstOrDefault(a => a.IsPrimary).CountyText : "",
AddressPostCode = c.Addresses.FirstOrDefault(a => a.IsPrimary) != null ? c.Addresses.FirstOrDefault(a => a.IsPrimary).PostCode : ""
}).OrderByDynamic(sortBy, sortDirection).Paginate((tableState.Page * tableState.PageSize), tableState.PageSize).ToListAsync();
在分配屬性 AddressCountry 、 AddressCounty 和 AddressPostCode (還有 2,3 個類似這樣的屬性需要從 PrimaryAddress 實體分配)
時,我指的是系結到物件的可用地址值串列中的 PrimaryAddress 項
有什么辦法可以避免每次設定屬性時都重復過濾到PrimaryAddress
我嘗試再添加一個 ContactAddress 型別的屬性 PrimaryAddress,然后在上面的 select 陳述句中我將值分配為
var dataset = await query.Select(c => new ContactListModel
{
-----
PrimaryAddress = c.Addresses.FirstOrDefault(a => a.IsPrimary),
AddressCountry = PrimaryAddress.Country.Name,
AddressCounty = PrimaryAddress.CountyText,
--
}).OrderByDynamic(sortBy, sortDirection).Paginate((tableState.Page * tableState.PageSize), tableState.PageSize).ToListAsync();
但我得到的錯誤是名稱'PrimaryAddress'在當前背景關系中不存在
OrderByDynamic & Paginate 用于處理排序和分頁,它們是我使用的輔助擴展。
uj5u.com熱心網友回復:
最方便的方法是切換到查詢語法并使用let:
var dataset = await (
from c in query
let primaryAddress = c.Addresses.FirstOrDefault(a => a.IsPrimary)
select new ContactListModel
{
Id = c.Id,
FirstName = c.FirstName,
LastName = c.LastName,
Email = c.Email,
EmailAlternative = c.EmailAlternative,
JobTitle = c.JobTitle,
CompanyName = c.Company.Name,
AddressCountry = primaryAddress.Country.Name,
AddressCounty = primaryAddress.CountyText,
AddressPostCode = primaryAddress.PostCode
}).ToListAsync();
請注意,我洗掉了空檢查。如果query是IQueryable來自物體框架(或另一個 O/R 映射器),那么它將被轉換為 SQL,從而消除了對空值檢查的需要。Ifquery是您可以使用的記憶體中物件串列c.Company?.Name,等等。
另請注意,您可能希望Addresses按某些屬性訂購,以便您可以控制哪個地址是“第一個”。
from - from通過使用查詢(或SelectMany在后臺)可以實作相同的目標:
var dataset = await (
from c in query
from primaryAddress in c.Addresses.Where(a => a.IsPrimary)
.Take(1).DefaultIfEmpty()
select new ContactListModel
{
Id = c.Id,
FirstName = c.FirstName,
LastName = c.LastName,
Email = c.Email,
EmailAlternative = c.EmailAlternative,
JobTitle = c.JobTitle,
CompanyName = c.Company.Name,
AddressCountry = primaryAddress.Country.Name,
AddressCounty = primaryAddress.CountyText,
AddressPostCode = primaryAddress.PostCode
}).ToListAsync();
添加DefaultIfEmpty()使查詢回傳沒有主要地址的聯系人,就像在第一個查詢中一樣。
如果query確實是IQueryable這樣,那么就資料庫引擎的查詢執行計劃而言,可能值得研究兩種備選方案中的哪一個生成最佳 SQL。在 EF 核心中,第二個替代方案只生成一個子查詢來獲取主地址,而第一個替代方案對每個primaryAddress屬性都執行此操作。
uj5u.com熱心網友回復:
那這個呢
.....
PrimaryAddress = c.Addresses.Select(x=>
new PrimaryAddress {
Country = x.Country.Name,
County = x.CountyText
}).FirstOrDefault(a => a.IsPrimary),
CompanyName = (c.Company != null) ? c.Company.Name : ""
}).ToListAsync();
您可以保留地址,也可以使用 AddressCountry、AddressCounty、AddressPostCode,您可以通過 ContactListModel getter 獲取它們
uj5u.com熱心網友回復:
通過雙重選擇,我的意思是:
var dataset = await query.Select(c => new { c, PA = c.Addresses.FirstOrDefault(a => a.IsPrimary) })
.Select(at => new ContactListModel
{
Id = at.c.Id,
FirstName = at.c.FirstName,
LastName = at.c.LastName,
Email = at.c.Email,
EmailAlternative = at.c.EmailAlternative,
JobTitle = at.c.JobTitle,
CompanyName = at.c.Company,
AddressCountry = at.PA.Country.Name,
AddressCounty = at.PA.CountyText,
AddressPostCode = at.PA.PostCode : ""
})
這是 Gert 在查詢語法中發布的方法語法形式(第一個示例)
我不喜歡生成的 SQL(在這種情況下或 Gert 的第一個),類似于(不準確,但應該給出這個想法):
SELECT
c.Id,
...
(SELECT TOP 1 Name FROM Addresses WHERE Id = c.AddressId AND IsPrimary = 1) Name,
(SELECT TOP 1 Country FROM Addresses WHERE Id = c.AddressId AND IsPrimary = 1) Country,
(SELECT TOP 1 PostCode FROM Addresses WHERE Id = c.AddressId AND IsPrimary = 1) PostCode
FROM
Contacts c
希望 SQLS 可以將其優化為僅進行一次查找。我認為我更喜歡過濾包含以獲得更直接的 JOIN 并使用映射庫(或空合并)來提取資料 C# 端。在添加有關您的 EF(C) 版本的資訊后發表評論,以便清楚這是否是一個選項
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/411350.html
標籤:
