2013-03-16 68 views
2

我有以下類(過於簡化):EF代碼優先 - 預先加載和過濾子類屬性(繼承)

public class Person 
{ 
    public int ID { get; set; } 
} 
public class Content 
{ 
    public int ID { get; set; } 
} 
public class Image : Content 
{ 
    public bool Private { get; set; } 
    public Person Author { get; set; } 
} 
public class Tag 
{ 
    public int ID { get; set; } 
    public Content Content { get; set; } 
    public Person Person { get; set; } 
} 

我想獲得的所有Tags其中ContentImageImage不是Private(同時熱切地加載Image的財產)。例如,試圖做到這一點,但不起作用:

var tags = context.Tags 
    .Include("Content.Author") 
    .Include("Person") 
    .Where(t => !((Image)t.Content).Private); 

我收到以下錯誤:

無法轉換類型「內容」輸入「圖像」。 LINQ to Entities僅支持投射EDM基元或枚舉類型。

並與Where條款中刪除:

一個指定的包含路徑無效。 EntityType'Content'不聲明名爲'Author'的導航屬性。

需要什麼樣的查詢和/或模型模式更改才能完成此方法?

+0

不是一個答案,但嘗試使用您的渴望加載與Lambda包括。 添加using語句System.Data。實體 和您的包含應該是context.Tags.Include(t => t.Content.Author).Include(t => t.Person) – 2013-03-16 17:18:01

+0

@Patrick我得到編譯器錯誤嘗試使用任何lambda使用EF的Include() 5.0。有什麼我需要能夠使用這些? – 2013-03-16 18:21:46

+0

您是否嘗試過右鍵單擊您的項目,添加引用,然後在Assemblies菜單選擇框架的彈出對話框中,搜索System.Data並從中包含它,看看是否有效。 - http://i.imgur.com/zr9kr70.png – 2013-03-16 18:24:36

回答

6

你可以寫過濾器的Where子句中的下列方式:

.Where(t => t.Content is Image && !(t.Content as Image).Private) 

然而,更大的問題是Include一部分。 Author屬性只存在於派生類型Image中,但Include將嘗試加載基類型Content(它不具有Author屬性),因爲這是Tag中的導航屬性Content的類型。你在這裏不能使用Include

你可以試着重寫查詢作爲投影:只要

var tags = context.Tags 
    .Where(t => t.Content is Image && !(t.Content as Image).Private) 
    .Select(t => new 
    { 
     Tag = t, 
     Image = t.Content as Image, // possibly this line is not needed 
     Author = (t.Content as Image).Author, 
     Person = t.Person 
    }) 
    .AsEnumerable() 
    .Select(x => x.Tag) 
    .ToList(); 

,你不要禁用更改跟蹤(與AsNoTracking例如)EF應該自動把對象圖在一起,使得加載標記具有填充的Content,Content.AuthorPerson屬性(就好像您已經使用Include加載了導航屬性)。

順便說一句:要包含派生類型導航屬性的功能請求here on UserVoice。這與您的情況並不完全相同,但在評論部分中,即使對於您的情況也是如此。

+0

這工作完美!感謝您的答案和UserVoice功能的鏈接。 – 2013-03-19 02:22:50

-1

嘗試改變類定義類似...

class Person 
{ 
    public int ID { get; set; } 
} 

class Content 
{ 
    public int ID { get; set; } 
} 

class Image : Content 
{ 
    public bool IsPrivate { get; set; } 
    public virtual Person Author { get; set; } 
} 

class Tag 
{ 
public int ID { get; set; } 
public Content Content { get; set; } 
public Person Person { get; set; } 
} 

私人似乎並不像一個好名字的屬性,因爲它與公共或私人聲明衝突。