簡體   English   中英

使用帶有條件過濾器的Include()連接兩個表

[英]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.

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