0

次のコードを Linq ステートメントに変換したいと思います。

                int x, y, z;
                List<POINT> l = new List<POINT>();

                foreach (NODE n in nodesEnumerable)
                {
                    x = n.propNodeNumber;
                    foreach (BOARD b in n.propNodeBoardList)
                    {
                        y = b.propBoardNumber;
                        foreach (DEVICE d in b.propBoardDeviceList)
                        {
                            z = d.propDeviceNumber;
                            if (d.propDeviceInstalled == DEVICE_INSTALLED_Types.Enabled)
                            {
                                POINT p = new POINT();
                                p.propPointNodeNumber = x;
                                p.propPointSlotNumber = y;
                                p.propPointAddressNumber = z;
                                p.propObjectDevice = d;

                                l.Add(p);
                            }
                        }
                    }
                }

                foreach (POINT pp in l)
                {
                    Console.WriteLine(pp.propObjectDevice.ToString());
                }

上記のコードを実装するために以下の Linq ステートメントを作成しましたが、4 つのパラメーターのうち 2 つを POINT オブジェクトに格納できるという点で部分的に機能します。コメント行は、値を取得できない 2 つのフィールドです。

Linq プロセス中にいくつかの中間結果を保存する必要がありますが、今はできません。

また、n.propDeviceNumber が d.propDeviceNumber である必要があると想定したときに、なぜ n.propDeviceNumber が機能するのかわかりません。

                list = from n in nodesEnumerable
                .SelectMany(b => b.propNodeBoardList)
                .SelectMany(d => d.propBoardDeviceList)
                       where (n.propDeviceInstalled == DEVICE_INSTALLED_Types.Enabled)
                       select (new POINT()
                       {
                           //propPointNodeNumber = 
                           //propPointSlotNumber = b.propBoardNumber,
                           propPointAddressNumber = n.propDeviceNumber,
                           propObjectDevice = n
                       });

                foreach (POINT p in list)
                {
                    Console.WriteLine(p.propObjectDevice.ToString());
                }

LIST<> NodeBoardList の代わりに BOARD[] BoardArray を使用したときに、以前のバージョンのコードで POINT を更新するために必要なすべての中間結果を保存できたという点で、Linq ステートメントを適切に機能させることができました。 LIST<> BoardDeviceList の代わりに DEVICE[] DeviceArray を使用しました。Linq ステートメントは以下のとおりです。

                list =
                    from n in nodesEnumerable
                    from b in n.BoardArray
                    from d in b.DeviceArray
                    where d.propDeviceInstalled == DEVICE_INSTALLED_Types.Disabled
                    select (new POINT()
                    {
                        propPointNodeNumber = n.propNodeNumber,
                        propPointSlotNumber = b.propBoardNumber,
                        propPointAddressNumber = d.propDeviceNumber,
                        propObjectDevice = d
                    });

                foreach (var p in list)
                {
                    Console.WriteLine(p.ToString());
                } 

配列を使用すると、Linq ステートメントを機能させることができましたが、リストを使用するようにすべてのコードを変換したため、Linq ステートメントを正しく機能させることができません。私のコードでリストを使用すると、この Linq ステートメントを機能させることを除いて、プログラムの他のすべての側面で非常にうまく機能します。

作成しなければならない同様の Linq ステートメントが多数あるため、この機能をハードコーディングする代わりに、Linq ステートメントを実際に使用したいと考えています。

提案をありがとう。

4

1 に答える 1

1

List も Array もIQueriableであるため、LINQ に関する限り違いはありません。問題はあなたのSelectMany()方法にあります。最後のスニペットのLINQが良かったのに、なぜそのように書くのかわかりません。

もちろん、2 番目のスニペットの 2 つのプロパティにはbandを使用できません。これらは以前のラムダ式からのものであるため、その下の LINQ クエリとは関係ありません。n

私はいくつかのダミークラスを作成し、linq を正常にコンパイルしました (これはほぼ正確にクエリです)。

        var nodes = new List<NODE>();
        var linq = from n in nodes
                   from b in n.propNodeBoardList
                   from d in b.propBoardDeviceList
                   where d.propDeviceInstalled == 1
                   select new POINT() 
                   {
                    propPointNodeNumber = n.propNodeNumber,
                    propPointSlotNumber = b.propBoardNumber,
                    propPointAddressNumber = d.propBoardDeviceNumber,
                    propObjectDevice = d
                   };

編集:さらに明確にするために、あなたが書いたとき

from n in nodesEnumerable
                .SelectMany(b => b.propNodeBoardList)
                .SelectMany(d => d.propBoardDeviceList)

メソッドのいわばLINQよりも「優先順位が高い」と考えると、実際には次のようになります。

  1. nodesEnumerable.SelectMany(b => b.propNodeBoardList)すべてのノードから平坦化されたものを返します。List<BOARD>それを呼び出しましょうbList
  2. bList.SelectMany(d => d.propBoardDeviceList)前の関数によって返されたすべてのボードから平坦化されたデバイス リストを返します
  3. n値を取得する実際のコレクションは 2. のデバイス リストであるため、 n は実際にはDEVICE. IntelliSense でマウス カーソルをその上に置くと、この事実を確認できます。それが解決することを願っています
于 2013-05-29T21:52:59.620 に答える