[英]left join in Linq query
我正在嘗試進行左連接,而不是linq查詢中的內連接。 我找到了與使用DefaultIfEmpty()
相關的答案,但我似乎無法使其工作。 以下是linq查詢:
from a in dc.Table1
join e in dc.Table2 on a.Table1_id equals e.Table2_id
where a.Table1_id == id
orderby a.sort descending
group e by new
{
a.Field1,
a.Field2
} into ga
select new MyObject
{
field1= ga.Key.Field1,
field2= ga.Key.Field2,
manySubObjects = (from g in ga select new SubObject{
fielda= g.fielda,
fieldb= g.fieldb
}).ToList()
}).ToList();
該查詢僅向我提供表1中具有表2中相應記錄的行。我希望表1中的每個記錄都填充到MyObject中,並且每個MyObject的manySubObjects中列出的0-n對應記錄列表。
更新:我嘗試了下面提到的“可能重復”的問題的答案。 我現在有以下代碼,即使沒有Table2記錄,也會為Table1中的每個項目提供一條記錄。
from a in dc.Table1
join e in dc.Table2 on a.Table1_id equals e.Table2_id into j1
from j2 in j1.DefaultIfEmpty()
where a.Table1_id == id
orderby a.sort descending
group j2 by new
{
a.Field1,
a.Field2
} into ga
select new MyObject
{
field1= ga.Key.Field1,
field2= ga.Key.Field2,
manySubObjects = (from g in ga select new SubObject{
fielda= g.fielda,
fieldb= g.fieldb
}).ToList()
}).ToList();
但是,使用此代碼,當table2中沒有記錄時,我將“manySubObject”作為一個列表,其中包含一個“SubObject”,其中包含“SubObject”屬性的所有空值。 如果table2中沒有值,我真正想要的是“manySubObjects”為null。
在回復您的更新時 ,要創建null列表,您可以在manySubObjects
的賦值中執行三元manySubObjects
。
select new MyObject
{
field1= ga.Key.Field1,
field2= ga.Key.Field2,
manySubObjects =
(from g in ga select g).FirstOrDefaut() == null ? null :
(from g in ga select new SubObject {
fielda= g.fielda,
fieldb= g.fieldb
}).ToList()
}).ToList();
在回復您的評論時 ,上述內容適用於Linq to Objects,但不適用於Linq to SQL。 Linq to SQL會抱怨它,“無法將表達式轉換為SQL而無法將其視為本地表達式。” 那是因為Linq無法將自定義的new SubObject
構造函數轉換為SQL。 為此,您必須編寫更多代碼以支持轉換為SQL。 請參閱LINQ to SQL查詢中的自定義方法和本文 。
我想我們已經充分回答了你關於左連接的原始問題。 考慮在Linq to SQL查詢中詢問有關使用自定義方法/構造函數的新問題。
我認為你想要的結果可以通過使用GroupJoin()給出
下面的代碼將生成一個類似的結構
Field1,Field2,List <SubObject> null如果為空
示例代碼
var query = dc.Table1.Where(x => Table1_id == id).OrderBy(x => x.sort)
.GroupJoin(dc.Table2, (table1 => table1.Table1_id), (table2 => table2.Table2_id),
(table1, table2) => new MyObject
{
field1 = table1.Field1,
field2 = table1.Field2,
manySubObjects = (table2.Count() > 0)
? (from t in table2 select new SubObject { fielda = t.fielda, fieldb = t.fieldb}).ToList()
: null
}).ToList();
Dotnetfiddle 鏈接
UPDATE
從你的評論我看到了這一點
ga.Select(g = > new SubObject(){fielda = g.fielda, fieldb = g.fieldb})
我認為應該是(取決於如何建立“ga”)
ga.Select(g => new SubObject {fielda = g.fielda, fieldb = g.fieldb})
請使用整個查詢更新您的問題,這將有助於解決問題。
**更新BIS **
sentEmails = //ga.Count() < 1 ? null :
//(from g in ga select g).FirstOrDefault() == null ? null :
(from g in ga select new Email{
email_to = g.email_to,
email_from = g.email_from,
email_cc = g.email_cc,
email_bcc = g.email_bcc,
email_subject = g.email_subject,
email_body = g.email_body }).ToList()
應該:
sentEmails = //ga.Count() < 1 ? null :
((from g in ga select g).FirstOrDefault() == null) ? null :
(from g in ga select new Email{
email_to = g.email_to,
email_from = g.email_from,
email_cc = g.email_cc,
email_bcc = g.email_bcc,
email_subject = g.email_subject,
email_body = g.email_body }).ToList()
檢查該組是否具有First,如果該組沒有任何記錄,則Time Stamp的Action.Name沒有要發送的電子郵件。 如果First不為null,則循環拋出組元素並創建Email列表,
var results =
(
// Use from, from like so for the left join:
from a in dc.Table1
from e in dc.Table2
// Join condition goes here
.Where(a.Id == e.Id)
// This is for the left join
.DefaultIfEmpty()
// Non-join conditions here
where a.Id == id
// Then group
group by new
{
a.Field1,
a.Field2
}
).Select(g =>
// Sort items within groups
g.OrderBy(item => item.sortField)
// Project required data only from each item
.Select(item => new
{
item.FieldA,
item.FieldB
}))
// Bring into memory
.ToList();
然后在內存中投影到非EF模型類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.