EF基于List<int>筛选AdminProfileRight表及CS1929报错解决
问题原因
CS1929编译错误是因为Contains方法的调用逻辑写反了:
d.MenuItemId是int类型,本身没有Contains方法,也无法接收List<int>类型的入参- 实际需要判断的是「单个MenuItemId是否存在于menuIds列表中」,应该用列表作为
Contains的调用主体,单个id作为入参
修正方案
场景1:删除现有权限中,和本次提交的menuIds重合的记录(常见于先删旧同项再插入新数据的逻辑)
public async Task Save(int profileId, int moduleId, int menuGroupId, List<AdminProfileRight> profileRights) { List<int> menuIds = profileRights.Select(pr => pr.MenuItemId).ToList(); IEnumerable<AdminProfileRight> existingProfileRights = await _unitOfWork.Repository<AdminProfileRight>().GetAll(epr => epr.ProfileId == profileId); // 修正Contains调用顺序 var itemsToDelete = existingProfileRights.Where(d => menuIds.Contains(d.MenuItemId)).ToList(); // 后续执行删除、新增逻辑... }
场景2:删除现有权限中,不在本次提交的menuIds里的旧记录(常见于全量覆盖权限的逻辑)
仅需要在判断逻辑前加取反符!即可:
var itemsToDelete = existingProfileRights.Where(d => !menuIds.Contains(d.MenuItemId)).ToList();
性能优化建议
如果你的GetAll方法支持将查询条件翻译成SQL执行(如EF Core等ORM框架),可以把过滤逻辑放到数据库侧执行,避免拉取全量权限数据到内存再过滤,提升性能:
// 直接在数据库查询阶段过滤出需要删除的记录,不需要拉取全部现有权限 var itemsToDelete = await _unitOfWork.Repository<AdminProfileRight>().GetAll(epr => epr.ProfileId == profileId && menuIds.Contains(epr.MenuItemId) // 此条件会被翻译成SQL的IN语句,数据库侧直接过滤 ).ToListAsync();
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

