实体框架 - 根据子集合获取父级

Posted

技术标签:

【中文标题】实体框架 - 根据子集合获取父级【英文标题】:Entity Framework - Get parents based on child collection 【发布时间】:2022-01-11 00:33:35 【问题描述】:

我应该检索票证,其中最后一条消息的 TeamId 不为空。

带代码:

var test1 = await _context.Tickets.Include(x => x.Messages)
            .Where(x => x.Messages.OrderByDescending(y => y.InsertDate).First().TeamId != null).ToListAsync();

var test2 = await _context.Tickets.Include(x => x.Messages)
            .Where(x => x.Messages.Last().TeamId != null).ToListAsync();

两者都返回所有票证,即使那些票证仅包含消息中 TeamId 为空的一个元素。

在最后一个元素的 TeamId 不为 null 的情况下,获取门票的正确查询是什么?

【问题讨论】:

你 100% 确定吗? Where 应该是决定性的,AFAIK 在这方面从来没有任何错误。但是,我们不知道您正在使用的 EF 版本和数据库提供程序。 尝试删除.Include(x => x.Messages) 该代码似乎不可重现。它似乎是 EF Core 代码,因为 .First() 不适用于 EF6,尽管我测试了一个具有可空属性的类似场景并且结果过滤正确。也许包括 Ticket & Message 的定义。 test2 示例将无法预测,因为 Last 没有 order-by 子句。 嗨,久等了。是的,我确认。为了测试,我尝试重新开始迁移,但结果是一样的。我使用的是最新版本的 ef core 6。这里是从 sql profiler shorturl.at/dhqB3 获得的查询截图。如您所见,IsDeleted 列上有一个全局过滤器。我看到它没有在 teamid 上添加指定的过滤器。 它与var test3 = await _context.Tickets.Where(x => x.Messages.OrderByDescending(y => y.InsertDate).Any(y => y.TeamId != null)).ToListAsync(); 一起正常工作,但它不适用于First。 Include(x => x.Messages) 没有区别 【参考方案1】:

如果您使用的是 EF 核心 5,那么过滤的包含可能会起作用,尽管我不记得是否支持 First()。试试看吧。

另外,我没有办法检查此代码 - 我是在手机上输入的,所以你应该验证它。

var test1 = await _context.Tickets
.Include(x => x.Messages.Where(x => x.Messages.OrderByDescending(y => y.InsertDate).First().TeamId != null))
.Where(x => x.Messages != null)
.ToListAsync();

【讨论】:

已测试(我将 OrderByDescending 移到 Where 之前),但结果没有改变,它返回 TeamId 为 null 的工单

以上是关于实体框架 - 根据子集合获取父级的主要内容,如果未能解决你的问题,请参考以下文章

实体框架按排序顺序加载子集合

Java递归遍历集合

停止加载子集合,如果我更新父集合

Firestore:获取带有和不带有子集合数据的集合[重复]

Firestore 获取根集合的所有文档和子集合

如何使用 Flutter 获取 Firestore 中每个集合的子集合