Pet*_*nar 12 inheritance entity-framework join eager-loading
在EF eager中,加载相关实体很容易.
但是在使用table-per-type模型加载数据时,我遇到了包括继承实体在内的困难.
这是我的模特:
实体:
ArticleBase
(基础文章实体)
ArticleSpecial
(继承自ArticleBase
)UserBase
(基本用户实体)
UserSpecial
(继承自UserBase
)Image
关系如图所示(省略许多列): alt text http://i48.tinypic.com/5x4kdc.jpg
实际上,我的用户总是类型UserSpecial
,因为UserBase
在另一个应用程序中使用,因此我们可以共享凭据.这是我有两个单独的表的唯一原因.UserBase
表格不能以任何形式或形式进行更改,因为其他应用程序会破坏.
我怎么想加载ArticleSpecial
既CreatedBy
和EditedBy
设置,使两者都是类型UserSpecial
(定义Image
关系)?
我尝试过这些选项(虽然不成功):
1. 使用lambda表达式:
context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated.Image")
.Include("UserEdited.Image");
Run Code Online (Sandbox Code Playgroud)
在这种情况下,问题是,无论是CreatedBy
和EditedBy
相关的UserBase
,没有定义Image
导航.所以我应该以某种方式将这两个UserSpecial
类型转换为:
context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated<UserSpecial>.Image")
.Include("UserEdited<UserSpecial>.Image");
Run Code Online (Sandbox Code Playgroud)
但当然使用泛型Include("UserCreated<UserSpecial>.Image")
不起作用.
2. 我尝试过使用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;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我只获取ArticleSpecial
没有设置相关属性的对象实例.我知道我应该以某种方式选择那些,但我不知道怎么做?
在我的LINQ中选择部分可以改为类似的东西
select new { articleSpecial, articleSpecial.UserCreated, articleSpecial.UserEdited };
Run Code Online (Sandbox Code Playgroud)
但图像仍未加载到我的上下文中.我在这种情况下的联接几乎不用于过滤articleSpecial结果,但它们不会将实体加载到上下文中(我想).
这似乎是当前版本的 Entity Framework (1.0) 的限制,看看这个相关的 SO 问题。
在您的情况下,在投影中包含相关的UserCreated和UserEdited属性是正确的解决方案。但是,如果您还想填充UserSpecial对象上的Image属性,则必须确保也包含该属性:
var results = from articleSpecial in ctx.ArticleBase.OfType<ArticleSpecial>()
select new
{
articleSpecial,
articleSpecial.UserCreated,
((UserSpecial)articleSpecial.UserCreated).Image,
articleSpecial.UserEdited,
((UserSpecial)articleSpecial.UserEdited).Image
};
Run Code Online (Sandbox Code Playgroud)
当然,此查询建立在所有 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;
});
Run Code Online (Sandbox Code Playgroud)
在后一个示例中,您也不需要在结果中包含UserSpecial和Image实体。相反,您只需在投影阶段访问ArticleSpecial实体上的导航属性,即可强制实体框架预先加载相关对象。
归档时间: |
|
查看次数: |
2831 次 |
最近记录: |