基于抽象实体 (EF CTP5) 的 Eager Loading 嵌套导航问题 [英] Problem with Eager Loading Nested Navigation Based on Abstract Entity (EF CTP5)

查看:21
本文介绍了基于抽象实体 (EF CTP5) 的 Eager Loading 嵌套导航问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 EF 模型的一部分如下所示:

I a portion of my EF model that looks like this:

总结:

  • 位置有很多帖子
  • Post 是一个抽象
  • 讨论源自帖子
  • 讨论有很多评论

现在,我要实现的查询:

Now, the query i'm trying to achieve:

获取有关位置 ID 1234 的信息,包括与这些讨论相关的任何讨论和评论.

我可以得到这样的讨论和评论:

I can get discussions and the comments like this:

var discussions = ctx.Posts
                     .OfType<Discussion>()
                     .Include(x => x.Comments)
                     .ToList();

但我似乎无法根据 位置 实体上的 帖子 导航获得它.

But i can't seem to get it based on the Posts navigation on the Location entity.

我已经试过了:

var locationWithDiscussionsAndComments = ctx
                    .Locations
                    .Include(x => x.Posts
                                   .OfType<Discussion>()
                                   .Select(y => y.Comments))
                    .SingleOrDefault();

编译成功,但出现错误:

Which compiles, but i get the error:

System.ArgumentException:包含路径表达式必须引用实体定义的属性,还可以选择使用嵌套属性或对 Select 的调用.参数名称:路径

System.ArgumentException: The include path expression must refer to a property defined by the entity, optionally also with nested properties or calls to Select. Parameter name: path

有什么想法吗?我可能会从帖子中倒退":

Any ideas? I could probably go "backwards" from the Posts:

var locationWithDiscussionsAndComments = ctx
                   .Posts
                   .Include(x => x.Location)
                   .OfType<Discussion>()
                   .Include(x => x.Comments)
                   .Where(x => x.LocationId == 1234)
                   .Select(x => x.Location)
                   .ToList();

但是就我的存储库而言,这既麻烦又语义错误(我不应该通过发布存储库来获取有关位置的信息).

But that is both hairy and semantically wrong in terms of my repositories (i shouldn't have to go through a post repository to get information about a location).

有什么想法吗?

编辑

所以经过深思熟虑后,我意识到 OfType 是一个过滤器操作.正如我们所知,EF 不支持预先加载过滤.唯一的选择是检索所有内容,或使用匿名类型投影.

So after having a bigger think about it, i realized that OfType<T> is a filter operation. As as we know, EF does not support filtering with eager loading. The only options are retrieving everything, or using anonymous type projection.

我无法检索所有内容,因为涉及的元数据太多了.所以我正在尝试匿名类型投影.

No way i can retrieve everything, as there is far too much meta data involved. So i'm attempting the anonymous type projection.

推荐答案

新的 Query 方法可能对您有所帮助:

The new Query method might help you:

var location = context.Locations.SingleOrDefault();

context.Entry(location)
       .Collection(l => l.Posts)
       .Query()
       .OfType<Discussion>()
       .Load();


我们可以在 Repository 类中添加一个新的 LoadProperty 泛型方法,以利用这个新的 QUery 方法:

We can add a new LoadProperty generic method to the Repository<T> class that leverages this new QUery method:

public void LoadProperty<TElement>(T entity, 
        Expression<Func<T, ICollection<TElement>>> navigationProperty,
        Expression<Func<TElement, bool>> predicate) where TElement : class
{
    _context.Set<T>().Attach(entity);

    _context.Entry(entity)         
            .Collection(navigationProperty)
            .Query()
            .Where(predicate)
            .Load();
}

使用 LoadProperty 方法:

Location location = _locationRepository.Find(1);
_locationRepository.LoadProperty(location, l => l.Posts, p => p is Discussion);

这篇关于基于抽象实体 (EF CTP5) 的 Eager Loading 嵌套导航问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆