我正在投资组合网站上,在产品页面上,我想显示同一类别的相关文章。
我创建了一种方法,允许我随机选择已定义类别的文章。不幸的是,当我添加OrderBy
子句以“启用”随机性时,我将无法再检索导航属性。
public async Task<IEnumerable<Article>> GetRandomArticlesByCategoryIdAsync(int categoryId, int numberOfArticles)
{
return await _ptitsBricosContext
.Articles
.OrderBy(a => Guid.NewGuid())
.Include(a => a.Pictures)
.Where(a => a.Category.Id == categoryId)
.Take(numberOfArticles)
.ToListAsync();
}
当我删除.OrderBy(a => Guid.NewGuid())
时,我正确地检索了相关的Pictures
,但是当我再次添加它时,我总是检索一个空的图片列表(即使我总是有结果)。
我有点卡住,我不明白为什么它会改变请求的行为。
答案 0 :(得分:2)
此问题是由随机订单,Take
运算符和子集合Include
的组合引起的。
EF Core使用单独的数据库查询处理集合Include
,将主查询与相关表连接起来。
由于此方案中的主查询返回不同的记录,因此第二个查询连接不会返回第一个查询结果的相关记录。相关集合可能为空或部分填充。
不幸的是,我认为这种情况没有好的解决方法。考虑将其发布到他们的GitHub问题跟踪器,看看他们会说些什么。
我看到的唯一相对有效的解决方法是修改主查询以仅返回PK,执行它并使用列表作为实际查询的条件:
var ids = await _ptitsBricosContext
.Articles
.OrderBy(a => Guid.NewGuid())
.Where(a => a.Category.Id == categoryId)
.Take(numberOfArticles)
.Select(a => a.Id)
.ToListAsync();
return await _ptitsBricosContext
.Articles
.Include(a => a.Pictures)
.Where(a => ids.Contains(a.Id))
.ToListAsync();