string param = request.QRBarang.Split('~') [1] 。
var a = await _db.A.FirstOrDefaultAsync(a => a.IdA == param)。
var b = await _db.B.FirstOrDefaultAsync(b => b.IdB1 == a.IdA) 。
var c = await _db.C.FirstOrDefaultAsync(c => c.IdC1 == b.IdB2)。
var d = c != null ?
? await _db.D.FirstOrDefaultAsync(d => d.IdD == c.IdC2)
: null。
var dto = new DTOFin { ...};
我還在學習LINQ,并試圖將該語法轉換為查詢運算式,但當c的值為null時,總是得到錯誤。 下面是我的嘗試:
var dto = (from a in _db.A
join b in _db.B on a.IdAequals b.IdB1
join c in _db.C onb.IdB2 equals c.IdC1
join d in _db.D on c.IdC2 equals d.IdD
where a.IdA == param && object.Equals(c.IdC2, d.IDD)
select new DTOFin { ...}).FirstOrDefaultAsync()。
我還嘗試使用join c in _db.C on b.IdB2 equals c?.IdC1但產生了
錯誤 CS8072 運算式樹lambda可能不包含空傳播的運算子。
我應該如何在查詢運算式中寫出第一個語法等價物?
uj5u.com熱心網友回復:
假設你已經正確地配置了導航屬性,那么這應該是可行的:
(我注意到EF的導航屬性是正確的)。
(我注意到EF6和EF Core的腳手架模板(用于從現有資料庫中自動生成物體類)已經為你做了這個。
(另外,我真的不喜歡C#的關鍵字風格的Linq運算式,因為為了做幾乎任何事情,你需要粘上Linq擴展方法,這與關鍵字風格的運算式在審美上有沖突。老實說,我現在想不出有什么好的理由來使用關鍵詞式的Linq運算式)。
我假設_db是你的DbContext。
using System.Linq;
using System.Data.Entity; //for EF6。
usingMicrosoft.EntityFrameworkCore.Query; //for EF Core
A a = await _db.A
.Include( a => a.B )
.Include( a => a.B.C )
.Include( a => a.B.C.D )
.Where( a => a.IdA == param )
.SingleOrDefaultAsync()。
//b, c, and d可以從A中得到:
B b = a.B。
C c = a.B.C;
D d = a.B.C?.D; // 看起來A.B和B.C是INNER JOIN而C.D是LEFT OUTER JOIN。Linq會根據你的模型配置使用正確的JOIN型別(INNER, LEFT等)。你不能僅僅從查詢中看出。
return new DTOFin(){ ... };
如果你沒有設定導航屬性(你應該......),那么你可以手動進行連接--但是這明顯是更糟糕的,因為Linq的.Join方法從來沒有被打算直接使用,因為你被期望使用導航屬性來代替。
- 注意,由于該 Linq 查詢被用于 Entity Framework,這意味著您的查詢必須可以用 SQL 表示......
- 這意味著你的查詢必須可以用SQL表示。
- 這意味著某些限制是適用的:例如不能使用
?.運算子--這就是你的問題。 - 其他限制包括不能使用你自己的自定義謂詞函式(除非它們也是
Expression<Func<>>),因為你不能直接將C#代碼放入SQL查詢中。
我相信下面的查詢應該有效,但是在不了解你的 EF 模型配置和資料庫設計的情況下,我無法確定 - 你在你的開篇問題帖子中沒有提供足夠的細節。
var a_b_c_d = await _db.A
.Join( _db.B, a => a.IdA , b => b.IdB1, ( a , b ) => new { a, b } )
.Join( _db.C, a_b => a_b.b.IdB2 , c => c.IdC1, ( a_b , c ) => new { a_b.a, a_b.b, c } )
.Join( _db.D, a_b_c => a_b_c.c.IdC2, d => d.IdD , ( a_b_c, d ) => new { a_b_c.a, a_b_c.b, a_b_c, d } )
.Where( a_b_c_d => a_b_c_d.a.IdA == param )
.SingleOrDefaultAsync()。
A a = a_b_c_d.a;
B b = a_b_c_d.b;
C c = a_b_c_d.c;
D d = a_b_c_d.d。
return new DTOFin() { ... };
uj5u.com熱心網友回復:
我認為這可以通過使用LINQ查詢語法來實作。
var dto = (from a in _db.A
join b in _db.B on a.IdA equals b.IdB1
join c in _db.C on b.IdB2 equals c.IdC1 into cTemp
from cT in cTemp.DefaultIfEmpty()
join d in _db.D on c.IdC2 equals d.IdDinto dTemp
from dT in dTemp.DefaultIfEmpty()
where a.IdA == param
select new DTOFin
{
...
}).FirstOrDefaultAsync()。
你可以從cT和dT變數中選擇c和d表的值。
。轉載請註明出處,本文鏈接:https://www.uj5u.com/net/310115.html
標籤:
