如何编写LINQ查询获取ID包含在指定列表中的实体集合
问题描述
我有一个User(用户)集合,对应实体类User.cs定义如下:
public Guid Id { get; set; } public bool isActiveUser { get; set; }
我需要实现一个接收ID列表的方法,基于传入的ID列表对数据库中的User表执行新增、更新、删除操作。
业务场景示例
- 数据库现有3条User记录,ID集合为
{1, 2, 3} - 方法传入的
List<Guid>类型userIds参数为{2, 3, 5} - 最终预期执行结果:
- 删除ID为1的记录
- 更新ID为2、3的记录(更新逻辑暂不展开)
- 新增ID为5的记录
- 操作完成后表中仅保留ID为2、3、5的记录
现有实现逻辑
目前通过集合的交集、差集运算将ID分为三类:
var existingUserIds = existingsUsers.Select(x=>x.Id).ToList(); var toBeDeleted = existingsUsers.Except(userIdsFromParameters).ToList(); var toBeUpdated = existingUsers.Intersect(userIdsFromParameters).ToList(); var toBeAdded = userIdsFromParameters.Except(existingUsers).ToList();
当前删除操作通过循环逐ID查询再执行删除,会产生大量冗余数据库访问,更新逻辑也存在同样的性能问题:
foreach (var id in toBeDeleted) { var obsoleteEntities = Users.Where(x => x.Id== id).ToList(); if (obsoleteEntities != null) { Users.RemoveRange(obsoleteEntities); } }
核心疑问
是否有可行的LINQ查询写法,可以直接获取所有ID包含在toBeDeleted列表中的用户,避免循环单ID查询的冗余操作?
解决方案
可以直接通过Contains方法实现批量匹配,无需循环逐ID查询,一次查询就能取出所有待删除的用户实体:
// 单次查询取出所有待删除实体 var obsoleteEntities = Users.Where(x => toBeDeleted.Contains(x.Id)).ToList(); // 批量删除 if (obsoleteEntities.Any()) { Users.RemoveRange(obsoleteEntities); }
优化提示
- 如果你使用EF Core等ORM访问数据库,这个写法会翻译成
WHERE Id IN (id1,id2,id3)格式的SQL,仅需一次数据库访问就能拿到所有待删除数据,相比循环逐ID查询的N次访问性能提升非常明显 - 原逻辑中
obsoleteEntities != null的判断是多余的:LINQ的Where方法返回值永远不会为null,判断是否存在数据用Any()即可 - 待更新的数据也可以用同样的逻辑批量取出,无需循环查询:
var toUpdateEntities = Users.Where(x => toBeUpdated.Contains(x.Id)).ToList(); // 遍历集合执行你的更新逻辑即可 - 如果使用支持批量操作的ORM(比如EF Core 7+),还可以直接执行批量删除,连先查询实体到内存的步骤都可以省略,性能更高:
// 直接生成批量删除SQL执行,无需查询实体 await Users.Where(x => toBeDeleted.Contains(x.Id)).ExecuteDeleteAsync();
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

