我正在尝试编写一个 LINQ 查询来显示与用户相关的地址。
但我也想显示引用无效用户的地址。在这种情况下,与用户相关的字段应设置为空。 词汇表:“无效用户”:在用户列表中找不到。
这是我的代码:
class Program
{
public static void Main(string[] args)
{
var users = GetUsers();
var addresses = GetAddresses();
var result = from address in addresses
from user in users
where user.Id == address.UserId
select new
{
address.Street,
address.Zipcode,
Id = address.UserId,
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}");
}
}
static List<User> GetUsers()
{
const string usersData = "[{\"id\":\"e135e5f9-64ed-4176-a543-ac7f09c15600\",\"name\":\"John Doe\",\"email\":\"[email protected]\"},{\"id\":\"d906db73-f711-4498-88b9-dc2d9d54ece5\",\"name\":\"James Scott\",\"email\":\"[email protected]\"}]";
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; }
}
}
使用上面的代码,与无效用户相关的地址将被忽略。
我期待收到这样的列表:
"Street": "206 Hazel St"
"Zipcode": "16853",
"Id": "e135e5f9-64ed-4176-a543-ac7f09c15600",
"Name": "John Doe",
"Email": "[email protected]"
},
{
"Street": "208 Mill St"
"Zipcode": "16853",
"Id": "d906db73-f711-4498-88b9-dc2d9d54ece5",
"Name": "James Scott",
"Email": "[email protected]"
},
{
"Street": "100 Turnpike St"
"Zipcode": "16853",
"Id": null,
"Name": null,
"Email": null
}]
首先,让我们更改您的查询以使用
join
:
var result =
from address in addresses
join user in users on address.UserId equals user.Id
select new
{
address.Street,
address.Zipcode,
Id = address.UserId,
Name = user.Name,
Email = user.Email,
};
我将
address.UserId
替换为 user.Id
。
现在我们可以将其更改为组
join
:
var result =
from address in addresses
join user in users on address.UserId equals user.Id into grouped_users
let maybe_single_user = grouped_users.SingleOrDefault()
select new
{
address.Street,
address.Zipcode,
Id = maybe_single_user?.Id,
Name = maybe_single_user?.Name,
Email = maybe_single_user?.Email,
};
grouped_users.SingleOrDefault()
为我们提供了用户或null
。然后使用 Elvis 运算符将 null
传播到输出中。
让我们精心设计
output
而不是抛弃一系列 Console.WriteLine
语句。
var outputs =
result
.Select(item =>
String
.Join(
Environment.NewLine,
new[]
{
$"Street: {item.Street}",
$"Zipcode: {item.Zipcode}",
$"Id: {item.Id}",
$"Name: {item.Name}",
$"Email: {item.Email}",
}));
Console.WriteLine(String.Join(Environment.NewLine + Environment.NewLine, outputs));
这给了我们:
Street: 206 Hazel St
Zipcode: 16853
Id: e135e5f9-64ed-4176-a543-ac7f09c15600
Name: John Doe
Email: [email protected]
Street: 208 Mill St
Zipcode: 16853
Id: d906db73-f711-4498-88b9-dc2d9d54ece5
Name: James Scott
Email: [email protected]
Street: 100 Turnpike St
Zipcode: 16853
Id:
Name:
Email: