2013-03-16 71 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; } 
} 

私人似乎并不像一个好名字的属性,因为它与公共或私人声明冲突。