如何在DbSet.Find()中包含相關表?

c# entity-framework-core

如果我想在EF7查詢中包含相關對象,那麼它很簡單:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .Where(t => t.SomeCondition == true)
                .ToList();

此外,在DbSet<T>上有一個很好的方法,可以通過其鍵輕鬆加載單個對象:

var myThing = db.MyThings.Find(thingId);

但是現在我想通過它的Id加載myThing ,以及它的RelatedThing 。不幸的是(並且可以理解) .Find()DbSet<T>的方法,而不是IQueryable<T> 。顯然我可以做到這一點:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .SingleOrDefault(t => t.MyThingId == thingId);

但我特別想使用.Find()方法,因為它很好且通用,而且我正在編寫一個通常加載記錄的方法以及由Expression<Func<T, object>>指定的“包含”關係。

有什麼建議怎麼做?

一般承認的答案

使用EF6是不可能的,我不認為EF Core會改變它。這是因為Find方法的主要目的是從本地緩存中引入已加載的實體,或者如果不存在則從數據庫加載它。因此,急切加載( Include )只能在後一種情況下使用,而在前者中則需要執行顯式加載。在單一方法中將兩者結合起來可能在技術上是可行的,但很難。

我認為您應該將FirstOrDefault (或SingleOrDefault )路由與急切加載相結合。您可以使用預先加載Repository泛型方法GetById中查看EF6的示例實現。可以像使用dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties一樣調整EF dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties用於查找PK屬性和構建謂詞的屬性。此外,由於EF Core包含更複雜(需要Include / ThenInclude鏈),您可能會發現這個線程有趣可以在Entity Framework Core中創建基於String的Include替代方案嗎?


熱門答案

將Find與Load結合使用,可顯式加載相關實體。在MSDN示例下面:

using (var context = new BloggingContext()) 
{ 
  var post = context.Posts.Find(2); 

  // Load the blog related to a given post 
  context.Entry(post).Reference(p => p.Blog).Load(); 

  // Load the blog related to a given post using a string  
  context.Entry(post).Reference("Blog").Load(); 

  var blog = context.Blogs.Find(1); 

  // Load the posts related to a given blog 
  context.Entry(blog).Collection(p => p.Posts).Load(); 

  // Load the posts related to a given blog  
  // using a string to specify the relationship 
  context.Entry(blog).Collection("Posts").Load(); 
}

這是MSDN鏈接



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow