9

我有這樣的方法:動態包含在查詢預先加載報表 - EF 4.3.1

public CampaignCreative GetCampaignCreativeById(int id) 
     { 
      using (var db = GetContext()) 
      { 
       return db.CampaignCreatives 
        .Include("Placement") 
        .Include("CreativeType")      
        .Include("Campaign") 
        .Include("Campaign.Handshake") 
        .Include("Campaign.Handshake.Agency") 
        .Include("Campaign.Product") 
        .AsNoTracking() 
        .Where(x => x.Id.Equals(id)).FirstOrDefault(); 
      } 
     } 

我想就包括動態列表。我試過了:

public CampaignCreative GetCampaignCreativeById(int id, string[] includes) 
     { 
      using (var db = GetContext()) 
      { 
       var query = db.CampaignCreatives; 

       foreach (string include in includes) 
       { 
        query = query.Include(include); 
       } 

       return query.AsNoTracking() 
        .Where(x => x.Id.Equals(id)).FirstOrDefault();      
      } 
     } 

但是沒有編譯。我得到這個錯誤:

不能隱式地將類型'System.Data.Entity.Infrastructure.DbQuery'轉換爲'System.Data.Entity.DbSet'。存在明確的轉換(您是否缺少演員?)

有誰知道如何製作包含動態列表?

感謝

+0

我做了一個插件,做到這一點,這裏是鏈接https://www.codeproject.com/Tips/1205294/Entity-Framework-Dynamic-Include-Hier archy – 2017-09-11 16:48:14

回答

9

充分利用query變量可查詢:

public CampaignCreative GetCampaignCreativeById(int id, string[] includes) 
{ 
    using (var db = GetContext()) 
    { 
     var query = db.CampaignCreatives.AsQueryable(); 
     foreach (string include in includes) 
     { 
      query = query.Include(include); 
     } 

     return query 
      .AsNoTracking() 
      .Where(x => x.Id.Equals(id)) 
      .FirstOrDefault();      
    } 
} 
+0

這需要什麼版本的EntityFramework? – cmour 2013-01-24 20:58:08

+0

我不明白。 IQueryable沒有包含方法。這不會編譯。 – dudeNumber4 2014-03-12 18:00:28

+0

有些項目你會得到這個解決方案的編譯錯誤。使用System.Data.Entity添加;訪問IQueryable上的Include擴展方法 – 2014-08-08 04:31:47

1

通過使用IQueryable<CampaignCreative>代替var將工作太給編譯器的提示。

IQueryable<CampaignCreative> query = db.CampaignCreatives; 
// or 
DbQuery<CampaignCreative> query = db.CampaignCreatives; 

當使用var編譯器推斷DbSet<T>query其比Include返回(這是DbQuery<T>(=基類的DbSet<T>)實施IQueryable<T>),所以不能將結果賦予類型更具體的query變量了。因此編譯器錯誤在query = query.Include(include)行。

24

我更喜歡定義包含的非字符串表達方式。主要是因爲它不依賴於魔術字符串。

對於示例代碼,它會是這個樣子:

public CampaignCreative GetCampaignCreativeById(int id) { 
    using (var db = GetContext()) { 
     return db.CampaignCreatives 
      .Include(cc => cc.Placement) 
      .Include(cc => cc.CreativeType)      
      .Include(cc => cc.Campaign.Select(c => 
       c.Handshake.Select(h => h.Agency))) 
      .Include(cc => cc.Campaign.Select(c => c.Product) 
      .AsNoTracking() 
      .Where(x => x.Id.Equals(id)) 
      .FirstOrDefault(); 
    } 
} 

而爲了讓那些充滿活力,這是如何做到這一點:

public CampaignCreative GetCampaignCreativeById(
    int id, 
    params Expression<Func<T, object>>[] includes 
) { 
    using (var db = GetContext()) { 
     var query = db.CampaignCreatives; 
     return includes 
      .Aggregate(
       query.AsQueryable(), 
       (current, include) => current.Include(include) 
      ) 
      .FirstOrDefault(e => e.Id == id); 
    } 
} 

這是用這樣的:

var c = dataService.GetCampaignCreativeById(
    1, 
    cc => cc.Placement, 
    cc => cc.CreativeType, 
    cc => cc.Campaign.Select(c => c.Handshake.Select(h => h.Agency)), 
    cc => cc.Campaign.Select(c => c.Product 
); 
+0

這真的很棒! – pomeroy 2013-10-21 12:28:36

+1

我上面說過了,但是我會在這裏說出來,以防萬一有人錯過它:有些項目你會得到這個解決方案的編譯錯誤。使用System.Data.Entity添加;在IQueryable上訪問Include擴展方法。 – 2014-08-08 04:32:25

+1

非常好,正是我想要達到的目標。 – Kramer00 2015-12-04 09:21:09