简体   繁体   English

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

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

First model:先拨model:

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

Second model:第二个model:

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

I have this method:我有这个方法:

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));
    }

adGroups input广告组输入

Object Object Name名称 Sid席德
[0] [0] WorkTeam1工作组1 Sid1 SID1
[1] [1] WorkTeam3 WorkTeam3 Sid2 SID2

gwtItems input gwtItems 输入

Object Object Id ID Name名称 Sid席德 Active积极的
[0] [0] 1 1个 WorkTeam1工作组1 Sid1 SID1 true真的
[1] [1] 2 2个 WorkTeam2工作组2 Sid2 SID2 true真的

desired result期望的结果

Object Object Id ID Name名称 Sid席德 Active积极的
[0] [0] 2 2个 WorkTeam3 WorkTeam3 Sid2 SID2 true真的

Demo is here演示在这里

I need to return an IEnumerable<GuidelinesWorkTeam> (Or other IEnumerable, because I need only adGroup.Name and gwtItem.Id ) element if they meet the above criteria, but replacing gwtItem.Name with adGroup.Name .如果满足上述条件,我需要返回一个IEnumerable<GuidelinesWorkTeam> (或其他 IEnumerable,因为我只需要adGroup.NamegwtItem.Id )元素,但用adGroup.Name替换gwtItem.Name

How can I do that?我怎样才能做到这一点?

Based on my understanding of your question, I would like to propose two different approaches to solve it:根据我对您问题的理解,我想提出两种不同的解决方法:

  • filtering the items in adGroups before associating the adGroups items with the gwtItems items在将adGroups项目与adGroups项目相关联之前过滤gwtItems中的项目
  • (filtering the items in gwtItems as you have already done, and then) associating the gwtItems items with the adGroups items (像您已经完成的那样过滤gwtItems中的项目,然后)将gwtItems项目与adGroups项目相关联

Depending on which variable ( adGroups or gwtItems ) benefits most from being filtered initially, you may choose which approach fits your use case best.根据哪个变量( adGroupsgwtItems )从最初过滤中获益最多,您可以选择最适合您的用例的方法。

Filtering the adGroups items, then associating them with the gwtItems items过滤adGroups项目,然后将它们与gwtItems项目相关联

Here, all applicable items from adGroups are grouped by Sid before each Sid -based grouping is associated with items from gwtItems based on the gwtItem's Sid value.在这里,在每个基于Sid的分组根据 gwtItem 的Sid值与来自gwtItems的项目相关联之前, adGroups中的所有适用项目都按Sid分组。 After associating adGroups groupings and gwtItems with equal Sid (and unequal Name , due to the initial filtering of adGroups ) using .Join() , we select each associated adGroup and gwtItem pair's adGroup.Name and gwtItem.Id in a tuple and use SelectMany() to flatten the collection (from a IEnumerable<IEnumerable< * >> to a IEnumerable< * > ).在使用.Join()adGroups分组和gwtItems与相等的Sid (和不相等的Name ,由于adGroups的初始过滤)相关联之后,我们 select 每个关联的 adGroup 和 gwtItem 对的adGroup.NamegwtItem.Id在一个tuple中并使用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(_ => _);
}

Associating the gwtItems items with the adGroups items (after filtering the gwtItems first)gwtItems项目与adGroups项目相关联(首先过滤gwtItems之后)

Here, the items from gwtItems are first associated with the items from adGroups based on the Sid property from the respective classes, using .Join() before a tuple containing relevant information is returned from the .Join() operation;在这里,在从.Join()操作返回包含相关信息的元组之前,首先使用.Join()根据各自类的Sid属性将来自adGroups gwtItems项目相关联; then, only the associated items that actually have different names are selected and converted to a simpler tuple.然后,只选择实际具有不同名称的关联项并将其转换为更简单的元组。

Your original filtering should possibly be included if it is probable that it will filter out many items from gwtItems ;如果您的原始过滤可能会从gwtItems中过滤掉许多项目,则可能应该包括在内; but it shouldn't be necessary to obtain the desired result.但这不是获得预期结果的必要条件。

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 ));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM