如何用LINQ关联两个列表:客户表与财务表(1对1关系)
用LINQ实现客户与薪资的关联
当然可以用LINQ轻松搞定这个需求!咱们的核心思路是把客户DTO和财务数据做左连接——这样既能保留所有客户,又能给有财务记录的客户填上薪资,没记录的就留空或者用默认值。结合你提供的代码和数据,这里有两种实用的实现方式:
方式一:直接修改已映射的DTO实例
如果允许修改已经映射好的CustomerDTO对象,可以用Select配合FirstOrDefault快速匹配对应财务记录:
// 先完成初始数据获取和DTO映射 IEnumerable<Customer> customers = await _customerService.GetCustomers(); IEnumerable<CustomerDTO> customerDTOs = _mapper.Map<IEnumerable<Customer>, IEnumerable<CustomerDTO>>(customers); IEnumerable<Finance> finances = await _financeService.GetFinances(); // 为每个DTO填充薪资 var customerDTOsWithSalary = customerDTOs.Select(dto => { // 1对1关系下,用FirstOrDefault精准匹配对应财务记录 var matchingFinance = finances.FirstOrDefault(f => f.CustomerId == dto.Id); if (matchingFinance != null) { dto.Salary = matchingFinance.Salary; } // 无匹配记录时,Salary保持默认值(比如null/空字符串) return dto; });
方式二:创建新的DTO实例(更符合不可变原则)
如果你不想修改原有的CustomerDTO对象,可以通过LINQ的左连接语法创建新实例,逻辑更清晰直观:
// 初始数据获取和映射同上 IEnumerable<Customer> customers = await _customerService.GetCustomers(); IEnumerable<CustomerDTO> customerDTOs = _mapper.Map<IEnumerable<Customer>, IEnumerable<CustomerDTO>>(customers); IEnumerable<Finance> finances = await _financeService.GetFinances(); // 左连接并填充薪资 var customerDTOsWithSalary = from dto in customerDTOs join finance in finances on dto.Id equals finance.CustomerId into financeMatches from matchedFinance in financeMatches.DefaultIfEmpty() select new CustomerDTO { Id = dto.Id, Name = dto.Name, Address = dto.Address, // 无匹配时用默认值,这里设为空字符串,你可以根据需求调整 Salary = matchedFinance?.Salary ?? string.Empty };
关键说明
- 因为是1对1关系,所以用
FirstOrDefault或者左连接后的DefaultIfEmpty()都能准确匹配,不会出现多数据冲突。 - 左连接的优势是能明确保留所有客户,即使没有对应财务记录也不会被过滤掉,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Tom el Safadi
相关产品推荐
相关产品推荐

