C#中用LINQ比较并更新List<UserTable>,实现大小写不敏感匹配
LINQ实现大小写不敏感关联与字段合并
核心思路
利用StringComparer.OrdinalIgnoreCase(关联场景)或string.Equals(..., StringComparison.OrdinalIgnoreCase)(字段比较场景)替代默认的大小写敏感逻辑,同时通过非空判断合并非空字段。
代码示例
1. 定义模拟实体类
// Excel导出的用户记录 public class ExcelUser { public string UserId { get; set; } public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } } // 数据库UserTable实体 public class UserTable { public string UserId { get; set; } public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public DateTime CreateTime { get; set; } }
2. 模拟测试数据
var excelUsers = new List<ExcelUser> { new ExcelUser { UserId = "A24070", Name = "张三", Email = null, Phone = "13800138000" }, new ExcelUser { UserId = "b35081", Name = null, Email = "lisi@example.com", Phone = "13900139000" } }; var dbUsers = new List<UserTable> { new UserTable { UserId = "a24070", Name = "张三_旧", Email = "zhangsan@example.com", Phone = null, CreateTime = new DateTime(2023, 1, 1) }, new UserTable { UserId = "B35081", Name = "李四_旧", Email = null, Phone = "13900139000_旧", CreateTime = new DateTime(2023, 2, 1) } };
3. 方法语法:内连接+大小写不敏感关联
直接在Join方法的最后一个参数传入比较器,实现UserId的大小写不敏感匹配,同时合并非空字段:
var mergedUsers = excelUsers.Join( dbUsers, excel => excel.UserId, db => db.UserId, (excel, db) => new UserTable { UserId = excel.UserId, // 可根据需求选择保留Excel或数据库的UserId Name = string.IsNullOrEmpty(excel.Name) ? db.Name : excel.Name, Email = string.IsNullOrEmpty(excel.Email) ? db.Email : excel.Email, Phone = string.IsNullOrEmpty(excel.Phone) ? db.Phone : excel.Phone, CreateTime = db.CreateTime }, StringComparer.OrdinalIgnoreCase // 关键:指定大小写不敏感比较器 ).ToList();
4. 查询语法:处理单字段大小写比较
如果需要在查询语法中实现大小写不敏感匹配,可通过string.Equals指定比较规则:
var mergedUsersQuery = from excel in excelUsers from db in dbUsers where excel.UserId.Equals(db.UserId, StringComparison.OrdinalIgnoreCase) select new UserTable { UserId = excel.UserId, Name = string.IsNullOrEmpty(excel.Name) ? db.Name : excel.Name, Email = string.IsNullOrEmpty(excel.Email) ? db.Email : excel.Email, Phone = string.IsNullOrEmpty(excel.Phone) ? db.Phone : excel.Phone, CreateTime = db.CreateTime };
5. 左连接场景(处理Excel有但数据库无的记录)
如果需要保留Excel中所有记录,即使数据库中没有匹配项,可使用GroupJoin+DefaultIfEmpty,同时注意空值判断:
var mergedLeftJoin = excelUsers.GroupJoin( dbUsers, excel => excel.UserId, db => db.UserId, (excel, dbGroup) => new { Excel = excel, DbUsers = dbGroup.DefaultIfEmpty() }, StringComparer.OrdinalIgnoreCase ).SelectMany( x => x.DbUsers, (x, db) => new UserTable { UserId = x.Excel.UserId, Name = string.IsNullOrEmpty(x.Excel.Name) ? db?.Name : x.Excel.Name, Email = string.IsNullOrEmpty(x.Excel.Email) ? db?.Email : x.Excel.Email, Phone = string.IsNullOrEmpty(x.Excel.Phone) ? db?.Phone : x.Excel.Phone, CreateTime = db?.CreateTime ?? DateTime.MinValue } ).ToList();
关键注意点
- 关联场景优先用
StringComparer.OrdinalIgnoreCase作为Join的比较器,性能更优。 - 单个字段比较时,用
string.Equals(a, b, StringComparison.OrdinalIgnoreCase)替代==,避免大小写敏感问题。 - 合并非空字段时,可根据业务需求调整优先级(比如优先用数据库值还是Excel值)。
- 如果是EF Core查询数据库,
StringComparer.OrdinalIgnoreCase会被转化为对应数据库的大小写不敏感查询逻辑(需确保数据库支持)。
内容的提问来源于stack exchange,提问作者Sapri s
相关产品推荐
相关产品推荐

