在EF eager中,相关实体是easy。
但是在使用每个类型的表模型加载数据时,我遇到了包括继承实体的困难。
这是我的模特:
实体:
ArticleBase
(基础文章实体)
ArticleSpecial
(继承自ArticleBase
)UserBase
(基本用户实体)
UserSpecial
(继承自UserBase
)Image
关系如图所示(省略多列): alt text http://i48.tinypic.com/5x4kdc.jpg
实际上,我的用户始终是UserSpecial
类型,因为UserBase
用于另一个应用程序,因此我们可以共享凭据。这是我有两个单独的表的唯一原因。 UserBase
表格不能以任何形式或形式进行更改,因为其他应用程序会中断。
我如何设置同时设置ArticleSpecial
和CreatedBy
的{{1}},以便两者都是EditedBy
类型(定义{{1}}关系)?
我尝试了这些选项(但未成功):
1。 使用lambda表达式:
UserSpecial
在这种情况下,问题是Image
和context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated.Image")
.Include("UserEdited.Image");
都与CreatedBy
相关,但未定义EditedBy
导航。所以我应该以某种方式将这两个类型转换为UserBase
类型:
Image
但当然在UserSpecial
中使用泛型不起作用。
2。 我尝试过使用LINQ查询
context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated<UserSpecial>.Image")
.Include("UserEdited<UserSpecial>.Image");
在这种情况下,我只获得Include("UserCreated<UserSpecial>.Image")
个对象实例而没有设置相关属性。我知道我应该以某种方式选择那些,但我不知道怎么做?
我的LINQ中的选择部分可以更改为
var results = from articleSpecial in ctx.ArticleBase.OfType<ArticleSpecial>()
join created in ctx.UserBase.OfType<UserSpecial>().Include("Image")
on articleSpecial.UserCreated.Id equals created.Id
join edited in ctx.UserBase.OfType<UserSpecial>().Include("Image")
on articleSpecial.UserEdited.Id equals edited.Id
select articleSpecial;
但图片仍未加载到我的上下文中。我在这种情况下的联接几乎不用于过滤articleSpecial结果,但它们不会将实体加载到上下文中(我想)。
答案 0 :(得分:3)
这似乎是当前版本的Entity Framework(1.0)中的限制请查看this related SO question。
在您的情况下,在投影中包含相关的 UserCreated 和 UserEdited 属性是正确的解决方案。但是,如果您还想在 UserSpecial 对象上填充图像属性,则必须确保包含该属性:
var results = from articleSpecial in ctx.ArticleBase.OfType<ArticleSpecial>()
select new
{
articleSpecial,
articleSpecial.UserCreated,
((UserSpecial)articleSpecial.UserCreated).Image,
articleSpecial.UserEdited,
((UserSpecial)articleSpecial.UserEdited).Image
};
当然,此查询建立在所有ArticleSpecial实体始终引用UserSpecial实体的假设之上,否则转换将失败。
如果这个假设并不总是正确,你可以使用LINQ扩展方法和多行lambda函数来表达相同的查询来执行安全的转换:
var results = ctx.ArticleBase
.OfType<ArticleSpecial>()
.AsEnumerable()
.Select(a =>
{
var userCreated = a.UserCreated as UserSpecial;
if (userCreated != null)
{
var image = userCreated.Image;
}
var userEdited = a.UserEdited as UserSpecial;
if (userEdited != null)
{
var image = userEdited.Image;
}
return a;
});
在后一个示例中,您还不需要在结果中包含 UserSpecial 和图像实体。相反,您只需在投影阶段访问 ArticleSpecial 实体上的导航属性,以强制Entity Framework急切加载相关对象。