[英]Joining two tables using Include() with conditional filter
我有現有的代碼要更新。 我想加入另一個名為Table3
。 由於查詢包含 Table2
,我想添加另一個帶有條件過濾器的.Include
並避免左連接。
當我加入.include
用.where
,我無法訪問t3Id
。 Intellisense只顯示表, Table3
而不是Id
字段。
我錯過了語法嗎? 謝謝。
Table1
有一個名為t1Id
的密鑰。
var query = (from e in ctx.Table1
.Include(r => r.Table2.Select(p => p.name))
.Include(rj => rj.Table3).Where(s => s.t1Id == t3Id)
select e).ToList();
Table1
將具有以下內容:
Id name
1 Joe
2 Mary
3 Harry
Table3
將具有以下內容:
t1Id title
3 staff
3 fulltime
預期結果:
1 Joe
2 Mary
3 Harry [{2, staff}, {3, fulltime}]
由於Harry在映射表中有記錄,因此他將擁有一組Table3
行。
我剛注意到你的EF評論。 使用Table1.Table3
,EF屬性Table1.Table3
應該已經加載相關實體而不使用where子句。
試試這個擴展方法
public static IEnumerable<TEntity> GetAllIncluding(this params Expression<Func<TEntity, object>>[] includesProperties)
{
return includesProperties.Aggregate<Expression<Func<TEntity, object>>,
IQueryable<TEntity>>(_dbSet, (current, includeProperty)
=> current.Include(includeProperty));
}
要使用該功能
var data = table1.GetAllIncluding(x => x.Table2, y => y.Table3);
這應該已經加載相關實體而不必過濾。
最好盡可能使用Select
而不是Include
。 Select
將允許您僅查詢您真正計划使用的屬性,從而更快地將所選數據從數據庫管理系統傳輸到您的流程。
例如,如果您查詢“學生與他們的學生”,那么Student
將擁有一個等於學校主鍵的外鍵。 因此,如果你有10號學校,你現在所有的5000名學生都將擁有一個價值為10的SchoolId
。將相同的值10發送超過5000次是有點浪費。
查詢數據時,請始終使用“選擇”。 如果您計划更新提取的數據,請僅使用Include。
您的查詢(在方法語法中):
var result = dbContext.Table1
.Where(table1Element => ...) // only if you don't want all elements of Table1
.Select(table1Element => new
{
// only select the table1 elements that you plan to use:
Id = table1Element.Id,
Name = table1Element.Name,
// Select the items that you want from Table 2:
Table2Items = table1Element.Table2
.Where(table2Element => ...) // only if you don't want all table2 elements
.Select(table2Element => new
{
// Select only the properties of table2 you plan to use:
Id = table2Element.Id,
Name = table2Element.Name,
...
// the following not needed, you already know the value:
// Table1Id = table2Element.table1Id, // foreign key
})
.ToList(),
// Table3: your new code:
Table3Items = table1Element.Table3
.Select(table3Element => new
{
// again: only the properties you plan to use
Id = table3Element.Id,
...
// the following not needed, you already know the value:
// Table1Id = table3Element.table1Id, // foreign key
})
.ToList(),
});
您看到讀者更容易看到他獲得了哪些屬性? 如果擴展了其中一個表,則畢竟不會在此查詢中獲取新屬性:用戶顯然不需要新屬性。 它們也沒有在此功能的規范中描述。
注意:因為我使用了new
,所以我的類型是匿名類型。 您只能在功能中使用它們。 如果需要返回獲取的數據,請將數據放入已知類中:
.Select(table1Element => new Table1Class()
{
Id = table1Element.Id,
Name = table1Element.Name,
...
});
再次:考慮不填寫外鍵,因為您可能不會使用它們
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.