如何使用LINQ显示含无效用户关联的地址列表(允许空值)
LINQ查询包含无效用户关联地址的解决方案
问题描述
需要编写LINQ查询展示所有地址,同时关联存在的用户信息;对于未在用户列表中找到对应用户的地址(即“无效用户”关联的地址),需将用户相关字段(Id、Name、Email)设为null。原代码使用内连接方式,导致此类地址被过滤,无法满足需求。
解决方案
使用LINQ的左外连接(Left Outer Join)实现,通过join...into结合DefaultIfEmpty()保留所有地址,无匹配用户时返回null用户对象,从而设置对应字段为null。
修改后的代码
class Program { public static void Main(string[] args) { var users = GetUsers(); var addresses = GetAddresses(); // 使用左外连接保留所有地址,无匹配用户时用户字段为null var result = from address in addresses join user in users on address.UserId equals user.Id into userGroup from user in userGroup.DefaultIfEmpty() select new { address.Street, address.Zipcode, Id = user?.Id, Name = user?.Name, Email = user?.Email }; foreach(var item in result) { Console.WriteLine($"Street: {item.Street}"); Console.WriteLine($"Zipcode: {item.Zipcode}"); Console.WriteLine($"Id: {item.Id}"); Console.WriteLine($"Name: {item.Name}"); Console.WriteLine($"Email: {item.Email}"); Console.WriteLine("---"); } } static List<User> GetUsers() { const string usersData = "[{\"id\":\"e135e5f9-64ed-4176-a543-ac7f09c15600\",\"name\":\"John Doe\",\"email\":\"johndoe@email.com\"},{\"id\":\"d906db73-f711-4498-88b9-dc2d9d54ece5\",\"name\":\"James Scott\",\"email\":\"jamesscott@email.com\"}]"; return JsonSerializer.Deserialize<List<User>>(usersData, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!; } static List<Address> GetAddresses() { const string addressData = "[{\"street\":\"206 Hazel St\",\"zipcode\":\"16853\",\"city\":\"Milesburg\",\"state\":\"PA\", \"country\": \"USA\",\"userId\":\"e135e5f9-64ed-4176-a543-ac7f09c15600\"},{\"street\":\"208 Mill St\",\"zipcode\":\"16853\",\"city\":\"Milesburg\",\"state\":\"PA\", \"country\": \"USA\",\"userId\":\"d906db73-f711-4498-88b9-dc2d9d54ece5\"},{\"street\":\"100 Turnpike St\",\"zipcode\":\"16853\",\"city\":\"Milesburg\",\"state\":\"PA\", \"country\": \"USA\",\"userId\":\"b84b9728-b657-4db9-8af7-45789983d931\"}]"; return JsonSerializer.Deserialize<List<Address>>(addressData, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!; } } internal class Address { public string Street { get; set; } public string Zipcode { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public Guid UserId { get; set; } } internal class User { public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } }
代码说明
- 左外连接逻辑:
join user in users on address.UserId equals user.Id into userGroup将每个地址与匹配的用户分组;from user in userGroup.DefaultIfEmpty()确保分组为空时返回null,而非过滤掉该地址。 - 空值处理:使用空值运算符
?.,当user为null时,Id、Name、Email自动设为null,符合需求。 - 原代码问题:原代码的
from address in addresses from user in users where user.Id == address.UserId等价于内连接,仅保留有匹配用户的地址,无法展示无效用户关联的地址。
内容的提问来源于stack exchange,提问作者André Arruda
相关产品推荐
相关产品推荐

