如何用C# LINQ高效检测同用户属性值组合冲突并设置IsConflict?
检测用户属性值组合重复并标记冲突
需求说明
针对相同UserId,检测AttributeName与AllowedValue.Value的组合是否重复。若某属性值组合在同一用户的多条ChangeAssignmentDto记录中存在,则将对应AllowedValue的IsConflict设为true。
输入数据
var inputDto = new List<ChangeAssignmentDto> { new ChangeAssignmentDto { AssignmentId = Guid.NewGuid(), AssignmentHash = Guid.NewGuid(), RoleId = Guid.Parse("50109670-BD0F-4531-8BE7-CBD12558CC02"), UserId = Guid.Parse("61eed904-c044-4dcc-8eb5-6a590e4a3d0a"), Attributes = new List<AttributeInfoDto> { new AttributeInfoDto { AttributeName = "Country", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "United Kingdom", IsConflict = false }, new AllowedValue { Value = "United States", IsConflict = false } } }, new AttributeInfoDto { AttributeName = "Attribute1", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "Item1", IsConflict = false }, new AllowedValue { Value = "Item2" , IsConflict = false} } } } }, new ChangeAssignmentDto { AssignmentId = Guid.NewGuid(), AssignmentHash = Guid.NewGuid(), RoleId = Guid.Parse("50109670-BD0F-4531-8BE7-CBD12558CC02"), UserId = Guid.Parse("61eed904-c044-4dcc-8eb5-6a590e4a3d0a"), Attributes = new List<AttributeInfoDto> { new AttributeInfoDto { AttributeName = "Country", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "United States", IsConflict = false } } }, new AttributeInfoDto { AttributeName = "Attribute1", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "Item1", IsConflict = false } } } } }, new ChangeAssignmentDto { AssignmentId = Guid.NewGuid(), AssignmentHash = Guid.NewGuid(), RoleId = Guid.Parse("50109670-BD0F-4531-8BE7-CBD12558CC02"), UserId = Guid.Parse("61eed904-c044-4dcc-8eb5-6a590e4a3d0a"), Attributes = new List<AttributeInfoDto> { new AttributeInfoDto { AttributeName = "Country", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "Australia", IsConflict = false } } }, new AttributeInfoDto { AttributeName = "Attribute1", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "Item1", IsConflict = false } } } } }, new ChangeAssignmentDto { AssignmentId = Guid.NewGuid(), AssignmentHash = Guid.NewGuid(), RoleId = Guid.Parse("50109670-BD0F-4531-8BE7-CBD12558CC02"), UserId = Guid.Parse("586e1a46-fef8-452a-b487-6012e538411d"), Attributes = new List<AttributeInfoDto> { new AttributeInfoDto { AttributeName = "Country", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "United States", IsConflict = false } } }, new AttributeInfoDto { AttributeName = "Attribute1", AllowedValues = new List<AllowedValue> { new AllowedValue { Value = "Item1", IsConflict = false } } } } } };
简洁高效的LINQ实现方案
// 统计用户下重复的(属性名, 属性值)组合 var conflictCombinations = inputDto .SelectMany(dto => dto.Attributes .SelectMany(attr => attr.AllowedValues .Select(val => new { dto.UserId, attr.AttributeName, val.Value }))) .GroupBy(x => new { x.UserId, x.AttributeName, x.Value }) .Where(g => g.Count() > 1) .ToDictionary(g => g.Key, _ => true); // 遍历原始数据标记冲突 foreach (var dto in inputDto) { foreach (var attr in dto.Attributes) { foreach (var val in attr.AllowedValues) { val.IsConflict = conflictCombinations.ContainsKey( new { dto.UserId, attr.AttributeName, val.Value }); } } }
实现思路
- 统计重复组合:通过
SelectMany逐层展开数据,提取所有用户的(属性名, 属性值)组合,按用户+属性名+属性值分组后筛选出出现多次的组合,存入字典以实现O(1)查询效率。 - 标记冲突状态:遍历原始数据集,对每个属性值检查是否属于重复组合,是则将
IsConflict设为true。
该方案仅需两次遍历(统计+标记),时间复杂度为O(N)(N为所有属性值的总数),兼顾代码简洁性与执行效率。
内容的提问来源于stack exchange,提问作者matta santhosh reddy
相关产品推荐
相关产品推荐

