LINQ不用于修改数据,而是用于查询数据和/或从数据中创建新数据。
我有一个用户集合,每个用户都有一个子成员集合。然后我还有一个俱乐部收藏。每个用户的子集合都填充了仅包含俱乐部ID的会员资格。我想要的是每个会员都包含与俱乐部ID匹配的俱乐部实体。
我的实体:
public class User
{
public string Name { get; set; }
public IEnumerable<Membership> Memberships { get; set; }
}
public class Membership
{
public Guid ClubId { get; set; }
public Club Club { get; set; }
}
public class Club
{
public Guid Id { get; set; }
public string Name { get; set; }
}
填充数据:
var club1Id = new Guid("FFEB77B9-1616-463B-B36E-F95F7E255FDE");
var club2Id = new Guid("7A6ECD38-5AEB-418B-9DD5-FBD777CE190C");
var users = new List<User>
{
new User
{
Name = "Patrick Stewart",
Memberships = new List<Membership>
{
new Membership { ClubId = club1Id },
new Membership { ClubId = club2Id }
}
},
new User
{
Name = "Brent Spiner",
Memberships = new List<Membership>
{
new Membership { ClubId = club1Id }
}
},
new User
{
Name = "Wesley Crusher",
Memberships = null
}
};
var clubs = new List<Club>
{
new Club
{
Id = club1Id,
Name = "Officers Club"
},
new Club
{
Id = club2Id,
Name = "Captains Club"
}
};
然后我需要一个LINQ查询,将匹配的Club对象添加到Membership对象中。
所以当我打印出这样的用户时:
foreach (var user in users)
{
Console.WriteLine($"User: {user.Name}");
if (user.Memberships != null)
{
foreach (var membership in user.Memberships)
{
Console.WriteLine($" Membership: {membership.Club?.Name}");
}
}
}
它看起来是这样的:
User: Patrick Stewart
Membership: Officers Club
Membership: Captains Club
User: Brent Spiner
Membership: Officers Club
User: Wesley Crusher
我想用LINQ表达式一次性完成,这样就不必涉及for循环。
我最终用这个LINQ表达式解决了它:
users = users.Select(user => new {
user,
Memberships = user.Memberships?
.GroupJoin(clubs, membership => membership.ClubId, club => club.Id, (membership, club) => new { membership, club})
.SelectMany(mc => mc.club.DefaultIfEmpty(), (mc, club) =>
{
mc.membership.Club = club;
return mc.membership;
})
})
.Select(x =>
{
x.user.Memberships = x.Memberships;
return x.user;
})
.ToList();
相反,使用嵌套的foreach
循环。
首先,创建一个Dictionary
,使查找Club
对象变得更容易:
var clubDict = clubs.ToDictionary(c => c.Id);
然后,使用clubDict
将每个Membership
修改为包括匹配的Club
实体:
foreach (var user in users.Where(u => u.Memberships != null))
foreach (var membership in user.Memberships)
membership.Club = clubDict[membership.ClubId];