2

我在 fluent LINQ 中遇到了将父母和孩子选择为一个的问题Ienumerable < anonymous type>

为简单起见:

  • 有一个列表commanders(每个区域的指挥官)。

  • 每个指挥官都有自己的 List of Soldiers。(并且每个Soldier人都有一个 bool 属性IsCanWinWar和一个Tool他用来战斗的)

我想列出每个指挥官(谁有一个或多个可以赢得战争的士兵)那个士兵使用的一个tool名字。

我不在乎一个指挥官是否有超过一个可以赢得战争的士兵。

指挥官所需要的只是一名士兵(谁可以赢得战争)的tool不管是哪个工具)。

输出是Ienumerable < anonymous type>匿名类型的位置:

{ 
  theCommander = [commanderObject] , 
  theToolName = [the tool name ]
} 

我做了一些事情,selectMany但它又长又丑。

是否有任何简短的查询(流利的查询)可以以更短的方式产生相同的结果?

public class Commander
    {
    public List<Soldier> lstSoldiers =new List<Soldier>(); //from db actually.
    }


    public class Soldier
    {
      public bool IsCanWinWar { get; set; }
      public string Tool { get; set; }
    }



void Main()
{
  List<Commander> lstCommanders = new List<Commander>(); //data source is actually from db.
  var MyIernumerableOfAnonymouseTypes= ?
}
4

2 回答 2

2
var MyIernumerableOfAnonymouseTypes = 
   lstCommanders.Select(c => new { 
                    theCommander = c, 
                    theToolName = c.lstSoldiers.Where(s => s.IsCanWinWar)
                                               .Select(s => s.Tool)
                                               .FirstOrDefault() })
                .Where(x => x.theToolName != null);

如果没有可以赢得战争的士兵,那么工具将是无效的。选择后将那些指挥官过滤掉即可。

顺便说一句,我认为这Soldiers是一个更好的属性名称lstSoldiers(它没有前缀,它是 PascalCase)。

于 2013-03-06T11:06:19.987 回答
1

第一种方法(稍后修订):

from commander in lstCommanders
where commander.lstSoldiers.Any(soldier => soldier.IsCanWinWar) // Consider only commanders who have at least one soldier who can win the war
select new
            {
                Commander = commander,
                Tool = (from soldier in commander.lstSoldiers
                        where soldier.IsCanWinWar // Consider tool originating from soldiers who can win the war
                        select soldier.Tool).FirstOrDefault()
            };

第二个更简洁更快:

from commander in lstCommanders
where commander.lstSoldiers.Any(soldier => soldier.IsCanWinWar)
select new { Commander = commander, Tool = commander.lstSoldiers.First(soldier => soldier.IsCanWinWar).Tool };

以流畅的方式:

lstCommanders.Where(commander => commander.lstSoldiers.Any(soldier => soldier.IsCanWinWar))
             .Select(  commander => new
                                         {
                                                 Commander = commander,
                                                 Tool = commander.lstSoldiers.First(soldier => soldier.IsCanWinWar).Tool
                                         });

一次迭代的第三个选项:

from commander in lstCommanders
let winner = commander.lstSoldiers.FirstOrDefault(soldier => soldier.IsCanWinWar)
where null != winner // Consider only commanders who have at least one soldier who can win the war
select new { Commander = commander, Tool = winner.Tool };
于 2013-03-06T11:13:02.940 回答