通過LINQ加載嵌套屬性

c# entity-framework-core linq

我正在嘗試使用LINQ獲取所有子實體的某個實體列表,但我使用的方法都沒有正常工作。這是類結構:

public class License {
   public virtual Product Product {get; set}
   . . . . . . 
   //some other License properties
   . . . . . . 
}

public class LicenseUser {
   public virtual Account User { get; set;}
   public virtual License License { get; set; }
}

我正在嘗試獲取某些用戶的許可證列表,但每個License對像也必須包含Product。我嘗試過的任何查詢都返回了Product屬性中帶有“null”值的許可證列表。
以下是LINQ查詢我嘗試過的示例:

var licenses = context.LicenseUsers
    .Include(lu => lu.License.Product)
    .Where(lu => lu.User.Id == 1)
    .Select(lu => lu.License)
    .ToList();

要么

var licenses = context.LicenseUsers
    .Include(lu => lu.License).ThenInclude(l => l.Product)
    .Where(lu => lu.User.Id == 1)
    .Select(lu => lu.License)
    .ToList();

我確信這些查詢得到的記錄包含對Products表的有效引用(ProductId字段不為null)。我還檢查了這個LINQ請求生成的SQL(使用診斷工具)。正如預期的那樣,它不包含Products表的JOIN語句。

有沒有正確的方法來獲得必要的結果?

一般承認的答案

這有點違反直覺,但問題是您的Select會過濾掉SQL查詢包含的內容。

因此,您可能希望強制EF將產品包含在SQL中(使用包含許可證及其產品的匿名對象),然後轉換為內存中的License集合:

var licenses = context.LicenseUsers
  .Include(lu => lu.License.Product)
  .Where(lu => lu.User.Id == 1)
  .Select(lu => new { lic = lu.License, prod = lu.License.Product } )
  .AsEnumerable()  // Here we have forced the SQL to include the product too
  .Select(lu => lu.lic)
  .ToList(); // Then we select (locally) only the license for convenience 
             // (so that our collection is of type License)
             // Since the SQL Query actually loaded the products
             // the references will be ok

熱門答案

好吧,我自己也很陌生,但這可能會給你一個想法。

根據這篇 MSDN文章,要急切地加載多個級別,你可以嘗試這樣的事情:

var licenses = context.LicenseUsers
    .Where(lu => lu.User.Id == 1)
    .Include(lu => lu.License.Select(p => p.Product))
    .ToList();

並且正如亞歷山大所說,檢查其他示例,Where()應該在Include()之前。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因