我的EF模型的一部分看起来像这样:
要点:
现在,我正试图实现的查询:
获取有关位置ID 1234的信息,包括与这些讨论相关的任何讨论和评论。
我可以得到讨论和这样的评论:
var discussions = ctx.Posts
.OfType<Discussion>()
.Include(x => x.Comments)
.ToList();
但我似乎无法根据位置实体上的帖子导航获取此内容。
我试过这个:
var locationWithDiscussionsAndComments = ctx
.Locations
.Include(x => x.Posts
.OfType<Discussion>()
.Select(y => y.Comments))
.SingleOrDefault();
编译,但我收到错误:
System.ArgumentException:包含路径表达式必须引用实体定义的属性,也可以引用嵌套属性或对Select的调用。 参数名称:路径
有什么想法吗?我可能会从帖子中“倒退”:
var locationWithDiscussionsAndComments = ctx
.Posts
.Include(x => x.Location)
.OfType<Discussion>()
.Include(x => x.Comments)
.Where(x => x.LocationId == 1234)
.Select(x => x.Location)
.ToList();
但就我的存储库而言,这在毛茸茸和语义上都是错误的(我不应该通过帖子库来获取有关位置的信息)。
有什么想法吗?
修改
因此,在对它进行更大的思考之后,我意识到OfType<T>
是一个过滤操作。据我们所知,EF不支持使用预先加载进行过滤。唯一的选择是检索所有内容,或使用匿名类型投影。
我无法检索所有内容,因为涉及的元数据太多了。所以我正在尝试匿名类型投影。
答案 0 :(得分:6)
新的查询方法可能会对您有所帮助:
var location = context.Locations.SingleOrDefault();
context.Entry(location)
.Collection(l => l.Posts)
.Query()
.OfType<Discussion>()
.Load();
我们可以为利用这种新Repository<T>
方法的QUery
类添加一个新的 LoadProperty 泛型方法:
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();
}
Location location = _locationRepository.Find(1);
_locationRepository.LoadProperty(location, l => l.Posts, p => p is Discussion);