我可以在Linq查询中选择多个对象吗?

Jam*_*Hay 34 c# linq list

我可以在选择中返回多个项目吗?例如,我有一个固定装置列表(想想橄榄球(或用于猛拉的足球)固定装置).每个夹具都包含一个主场和客场球队以及主客场得分.我想得到所有吸引的球队.我想用类似的东西

IEnumerable<Team> drew = from fixture in fixtures
                         where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
                         select fixture.HomeTeam && fixture.AwayTeam;
Run Code Online (Sandbox Code Playgroud)

我知道这种语法不正确,我不知道是否可以这样做.我需要两个查询然后将它们连接起来吗?

编辑:这真的是一个学习的东西,所以以任何特定的方式实现这一点并不重要.基本上,在这个阶段,我想要的是已经绘制的球队列表.一个示例用法可能是对于给定的灯具列表,我可以找到所有绘制的球队,这样我就可以在一个表中更新他们的积分1分(胜利为3,亏损为0).

Ant*_*lev 33

101 LINQ样本,即选择 - 匿名类型1

... select new { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam };
Run Code Online (Sandbox Code Playgroud)


cod*_*ast 26

以下将返回IEnumerable <Team>:

IEnumerable<Team> drew =
    from fixture in fixtures
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
    from team in new[]{fixture.HomeTeam, fixture.AwayTeam}
    select team;
Run Code Online (Sandbox Code Playgroud)

或者,使用流畅的LINQ风格:

IEnumerable<Team> drew =
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    .SelectMany(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam});
Run Code Online (Sandbox Code Playgroud)

展平和FlatMap

此要求通常称为"扁平化".也就是说,拍摄<<物品集合>>的集合并将其转换为<物品集合>.

SelectMany两个地图(一个团队阵列的固定)和扁平化(一系列团队阵列到一系列团队).它类似于Java和JavaScript等其他语言中的"flatMap"功能.

可以将Mapping和Flattening分开:

IEnumerable<Team> drew =
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    // map 
    .Select(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam})
    // flatten
    .SelectMany(teams => teams);
Run Code Online (Sandbox Code Playgroud)

其他方法

迭代器块

使用迭代器块可以实现相同的效果,但我怀疑这很少是最好的方法:

IEnumerable<Team> Drew(IEnumerable<Fixture> fixtures){
    var draws = 
      fixtures
      .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore));

    foreach(var fixture in draws){
        yield return fixture.HomeTeam;
        yield return fixture.AwayTeam;
    }
}
Run Code Online (Sandbox Code Playgroud)

联盟

联盟也是一种选择,但有可能产生上述不同的结果:

  1. 结果的顺序会有所不同.返回所有Home结果然后返回所有Away结果.

  2. Union枚举灯具两次,因此,根据灯具的实施方式,可能会在两次通话之间更新灯具.例如,如果在调用之间添加了新的绘制夹具,则可以返回Away团队,但不能返回主队.

正如迈克鲍威尔所描述:

IEnumerable<Team> drew =
    ( from fixture in fixtures
      where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
      select fixture.HomeTeam
    ).Union(
      from fixture in fixtures
      where fixture.Played  && (fixture.HomeScore == fixture.AwayScore)
      select fixture.AwayTeam );
Run Code Online (Sandbox Code Playgroud)

根据灯具的采购/实施方式,可能值得考虑"缓存"绘制的灯具以避免必须两次枚举灯具.

var draws = 
    ( from fixture in fixtures
      where fixture.Played  && (fixture.HomeScore == fixture.AwayScore)
      select fixture
    ).ToList();

IEnumerable<Team> drew =
    (from draw in draws select draw.HomeTeam)
    .Union(from draw in draws select draw.AwayTeam);
Run Code Online (Sandbox Code Playgroud)

或者使用流畅的风格:

var draws = 
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    .ToList();

IEnumerable<Team> drew =
    draws.Select(fixture => fixture.HomeTeam)
    .Union(draws.Select(fixture => fixture.AwayTeam));
Run Code Online (Sandbox Code Playgroud)

修改Fixture类

可以考虑将"ParticipatingTeams"添加到Fixture类中以获得:

IEnumerable<Team> drew =
    from fixture in fixtures
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
    from team in fixture.ParticipatingTeams
    select team;
Run Code Online (Sandbox Code Playgroud)

但正如@MattDeKrey所指出的那样,需要改变合同.

代码示例

代码示例可在Repl.it获得

  • 第一个查询的+1 - 不需要更改合同,并且比主要答案更有效. (3认同)

Mik*_*ell 22

我认为你正在寻找如下的Union方法:

IEnumerable<Team> drew = (from fixture in fixtures
                     where fixture.Played 
                        && (fixture.HomeScore == fixture.AwayScore)
                     select fixture.HomeTeam)
                     .Union(from fixture in fixtures
                     where fixture.Played 
                        && (fixture.HomeScore == fixture.AwayScore)
                     select fixture.AwayTeam);
Run Code Online (Sandbox Code Playgroud)


Mik*_*lum 14

我自己拿了一个刺,我想出了与'依赖'相同的版本.

使用查询理解语法:

IEnumerable<Team> drew =
    from fixture in fixtures
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
    from team in new[]{fixture.AwayTeam, fixture.HomeTeam}
    select team;
Run Code Online (Sandbox Code Playgroud)

使用lambda和扩展方法:

IEnumerable<Team> drew =
    fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore)
    .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam});
Run Code Online (Sandbox Code Playgroud)

编辑:我不知道团队是否可能在您的数据库中多次播放和绘制,但如果可能,那么您可能想要使用Distinct查询运算符:

IEnumerable<Team> drew =
    (from fixture in fixtures
     where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
     from team in new[]{fixture.AwayTeam, fixture.HomeTeam}
     select team).Distinct();
Run Code Online (Sandbox Code Playgroud)

要么:

IEnumerable<Team> drew =
    fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore)
    .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam})
    .Distinct();
Run Code Online (Sandbox Code Playgroud)


BC.*_*BC. 6

或者您可以定义一个类型来保存所有数据:

IEnumerable<TeamCluster> drew = from fixture in fixtures
                         where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
                         select new TeamCluster {
                             Team1 = fixture.HomeTeam,
                             Team2 = fixture.AwayTeam,
                             Score1 = fixture.HomeScore,
                             Score2 = fixture.AwayScore
                         };

class TeamCluster {
    public Team Team1 { get; set; }
    public Team Team2 { get; set; }
    public int Score1 { get; set; }
    public int Score2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)


Awe*_*own 5

编辑:对不起,误解了你原来的问题,所以重写了答案.

您可以使用"SelectMany"运算符来执行您想要的操作:

IEnumerable<Team> drew =
           (from fixture in fixtures
            where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
                  select new List<Team>()
                             { HomeTeam = fixture.HomeTeam,
                               AwayTeam = fixture.AwayTeam
                             }).SelectMany(team => team);
Run Code Online (Sandbox Code Playgroud)

这将返回一个扁平的团队列表.