C# Linq 查询连接两个列表并将结果分配给新列表

C# Linq query to join two lists and assign the result to new list

第一个模型:

public class Group
{
    public string Name { get; set; } 
    public string Sid { get; set; }
}

第二个模型:

public class GuidelinesWorkTeam
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Sid { get; set; }
    public bool Active { get; set; }
}

我有这个方法:

public IEnumerable<GuidelinesWorkTeam> GetWorkTeamsWhereChangeName(
       IEnumerable<Group> adGroups,
       IEnumerable<GuidelinesWorkTeam> gwtItems)
    {
        return gwtItems.Where(gwtItem => adGroups.Any(adGroup => gwtItem.Sid == adGroup.Sid && gwtItem.Name != adGroup.Name));
    }

广告组输入

Object Name Sid
[0] WorkTeam1 Sid1
[1] WorkTeam3 Sid2

gwtItems 输入

Object Id Name Sid Active
[0] 1 WorkTeam1 Sid1 true
[1] 2 WorkTeam2 Sid2 true

想要的结果

Object Id Name Sid Active
[0] 2 WorkTeam3 Sid2 true

演示是 here

我需要 return 一个 IEnumerable<GuidelinesWorkTeam>(或其他 IEnumerable,因为我只需要 adGroup.NamegwtItem.Id)元素,如果它们满足上述条件,但替换gwtItem.NameadGroup.Name.

我该怎么做?

根据我对你问题的理解,我想提出两种不同的解决方法:

  • 在将 adGroups 项与 gwtItems 项关联之前过滤 adGroups 中的项
  • (过滤 gwtItems 中的项目,然后)将 gwtItems 项目与 adGroups 项目相关联

根据哪个变量(adGroupsgwtItems)从最初过滤中获益最多,您可以选择最适合您的用例的方法。

过滤 adGroups 项,然后将它们与 gwtItems 项相关联

这里,在每个基于 Sid 的分组根据 gwtItem 的 Sid 值。在使用 .Join(), we select each associated adGroup and gwtItem pair's adGroup.Name and gwtItem.Id in a tupleadGroups 分组和 gwtItems 与相等的 Sid(并且不相等的 Name,由于 adGroups 的初始过滤)相关联并使用SelectMany() 将集合展平(从 IEnumerable<IEnumerable< * >>IEnumerable< * >)。

public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
    IEnumerable<Group> adGroups,
    IEnumerable<GuidelinesWorkTeam> gwtItems)
{
    return adGroups
        .Where(adGroup => gwtItems.Any(gwtItem => 
            gwtItem.Sid == adGroup.Sid &&
            gwtItem.Name != adGroup.Name))
        .GroupBy(adGroup => adGroup.Sid)
        .Join(gwtItems,
            grouping => grouping.Key,
            gwtItem => gwtItem.Sid,
            ( grouping, gwtItem ) => grouping
                .Select(adGroup => ( adGroup.Name, gwtItem.Id )))
        .SelectMany(_ => _);
}

gwtItems 项目与 adGroups 项目相关联(先过滤 gwtItems 之后)

这里,来自 gwtItems 的项目首先与来自 adGroups 的项目相关联,基于来自各自 类 的 Sid 属性,使用.Join() 在从 .Join() 操作返回包含相关信息的元组之前;然后,仅选择实际具有不同名称的关联项目并将其转换为更简单的元组。

如果您的原始过滤很可能会从 gwtItems 中过滤掉许多项目,则应该包括在内;但它不应该是获得所需结果的必要条件。

public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
   IEnumerable<Group> adGroups,
   IEnumerable<GuidelinesWorkTeam> gwtItems)
{
    return gwtItems
        // Original filtering
        .Where(gwtItem => adGroups.Any(adGroup => 
            gwtItem.Sid == adGroup.Sid &&
            gwtItem.Name != adGroup.Name))
        // Association and final filtering
        .Join(adGroups,
            gwtItem => gwtItem.Sid,
            adGroup => adGroup.Sid,
            ( gwtItem, adGroup ) => ( 
                ChangedName: gwtItem.Name != adGroup.Name,
                Name: adGroup.Name,
                Id: gwtItem.Id))
        .Where(workTeam => workTeam.ChangedName)
        .Select(workTeam => ( workTeam.Name, workTeam.Id ));
}