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();
LINQ不用于修改数据,而是用于查询数据和/或从数据中创建新数据。

相反,使用嵌套的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];

最新更新