2

親と子を1つに選択する際に流暢なLINQで問題が発生しましたIenumerable < anonymous type>

簡単にするために :

  • commanders(各地域の指揮官)の一覧があります。

  • 各司令官には独自の List of Soldiersがあります。(そして、それぞれSoldierに bool プロパティIsCanWinWarと、Tool彼が戦うために使用する a があります)

指揮官(戦争に勝つことができる兵士が1 人以上いる人)、その兵士が使用する1 つの名前をリストしたいと思います。tool

指揮官が戦争に勝つことができる兵士を複数持っていても、私は気にしません。

司令官が必要とするのは、その兵士 (戦争に勝つことができる) の 1 人からの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
                                         });

1 回の繰り返しによる 3 番目のオプション:

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 に答える