繁体   English   中英

实体框架。加载子类属性的Quering父实体

[英]Entity framework. Quering parent entity with subclass property loaded

有一个简单的域名..

public abstract class UserComment
{
    public string Text { get; set; }
}

public class BlogComment : UserComment
{
    public Blog Blog { get; set; }
}

public class PhotoComment : UserComment
{
    public Photo Photo { get; set; }
}

有没有办法查询UserComment类型的所有实体与属性博客和照片加载?

var comment = DbContext.Set<UserComment>()
    .Include(x => x.Blog) // will not compile
    .Include(x => x.Photo) // will not compile
    .FirstOrDefault();

if (comment is PhotoComment )
{
    string url = (comment as PhotoComment).Photo.Url;
}
if (comment is BlogComment)
{
    var dateCreated = (comment as BlogComment).Blog.DateCreated;
}

谢谢!

您可能需要两个查询才能获得结果。 如果你只想要第一个元素( FirstOrDefault )显式加载 - 正如你在评论中提到的那样 - 是一个很好的方法:

var comment = DbContext.Set<UserComment>().FirstOrDefault();

if (comment is BlogComment)
    DbContext.Entry(comment as BlogComment).Reference(bc => bc.Blog).Load();
else if (comment is PhotoComment)
    DbContext.Entry(comment as PhotoComment).Reference(pc => pc.Photo).Load();

如果你想加载一个UserComment列表,它不是最好的解决方案,因为它需要迭代加载的UserComment并为每个元素调用显式加载,这将导致许多查询。

对于列表,您可以使用以下方法,该方法也只生成两个查询:

IEnumerable<UserComment> blogComments = DbContext.Set<UserComment>()
    .OfType<BlogComment>()
    .Include(bc => bc.Blog)
    .Cast<UserComment>()
    .AsEnumerable();

IEnumerable<UserComment> photoComments = DbContext.Set<UserComment>()
    .OfType<PhotoComment>()
    .Include(pc => pc.Photo)
    .Cast<UserComment>()
    .AsEnumerable();

List<UserComment> comments = blogComments.Concat(photoComments).ToList();

由于使用了AsEnumerable()因此将运行两个单独的数据库查询,并将结果连接到内存中的单个集合。

LINQ-to-Entities支持Cast但由于某种原因,无法删除两个AsEnumerable()转换以仅获取单个数据库查询并将结果连接到数据库中。 代码仍然会编译,但我有一个关于无效Include路径的运行时异常。

我已经使用EF 4.1进行了测试。 在没有使用EF 5.0的AsEnumerable()情况下测试查询以查看它是否仍然失败可能是值得的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM