Alb*_*ori 2 c# inheritance entity-framework ef-code-first
我有以下课程(过于简化):
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; }
}
Run Code Online (Sandbox Code Playgroud)
我想获得所有Tags
在Content
是Image
与Image
不是Private
(而急切地加载的属性Image
).尝试执行此操作但不起作用的示例:
var tags = context.Tags
.Include("Content.Author")
.Include("Person")
.Where(t => !((Image)t.Content).Private);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
无法将类型"内容"转换为"图像"类型.LINQ to Entities仅支持转换EDM原语或枚举类型.
并Where
删除该条款:
指定的包含路径无效.EntityType'Content'不会声明名为'Author'的导航属性.
我需要什么样的查询和/或模型架构更改才能完成此方法?
您可以Where
通过以下方式在子句中编写过滤器:
.Where(t => t.Content is Image && !(t.Content as Image).Private)
Run Code Online (Sandbox Code Playgroud)
然而,更大的问题是这个Include
部分.该Author
属性只存在派生型Image
,但Include
将尝试加载基本类型Content
(它不具有Author
属性),因为这是导航属性的类型Content
在Tag
.你不能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();
Run Code Online (Sandbox Code Playgroud)
只要您不要禁用更改跟踪(带AsNoTracking
为例)EF应该自动把对象图在一起,使得加载标签具有填充Content
,Content.Author
和Person
财产(就好像你曾与装载的导航属性Include
).
BTW:在UserVoice上请求包含派生类型的导航属性的功能.它与您的情况不完全相同,但在评论部分中甚至是针对您的场景的请求.