2

私の問題を説明するために、いくつかの基本的な簡素化された例を使用します。

私はクラスを持っています:

class Item
{
   int ID;
   bool Selected;
}

Itemここで、クラスのリストが 2 つあるとします。

List<Item> ListA = GetListA();
List<Item> ListB = GetListB();

次に、 のすべてのアイテムを含む 3 番目のリストを作成しますListB。重要なことは、一致 (同じID) が見つかった場合はその値ListAを使用したいということです。SelectedSelectedListB

次のように 3 番目のリストを作成しています。

List<Item> ListC = from item in ListB 
select new Item
{
   ID = item.ID,
   Selected = item.Selected// <-- should use value form ListA if available
};

重要: 無知だと思われたくないのですが、作成方法を変更したくありませんListC。つまり、「linq select」メソッドを使用し、値を割り当てる「ワンライナー」を使用したいということSelectedです...うまく機能するリストを作成する方法が他にもあることは知っていますが、私は何も新しいことを学びません。


私はこれまでにいくつかのことを試しました...

ListAこれが機能することはわかっていますが、 2回クエリしたくありません。

Selected = ListA.Any(x => x.ID == item.ID) ? ListA.First(x => x.ID == item.ID).Selected : item.Selected

私も使ってみDeafultIfEmptyましたが、この状況では正しいとは思いません...うまくいかなかったので、ListA空だった方が使いやすいようです(気にしません)

4

2 に答える 2

7

コードの最後の行を次のように変更できます。

Selected = (ListA.FirstOrDefault(x => x.ID == item.ID) ?? item).Selected;

のためDefaultIfEmptyに、あなたがしなければならないでしょう

Selected = ListA.Where(x => x.ID == item.ID).DefaultIfEmpty(item)
                                                       .First().Selected;

従うのは難しいですが、本質的に同じことを行います。

Dominic が以下で述べているように、SingleOrDefault/Singleの代わりにを使用すると、同じFirstOrDefault/First項目が 2 つ見つかった場合に例外が発生します。これは導入したいチェックかもしれません。ListAID

(これを行うためのより良い/より効率的な方法がありますが、あなたが言うように、まったく異なる方法を使用するのではなく、この方法を修正したいと考えています。)

于 2012-11-29T10:56:26.087 に答える
2

これはどうですか?

var query = from b in ListB
        join a in ListA
            on b.ID equals a.ID into g
        from r in g.DefaultIfEmpty(b)
        select new Item { ID = b.ID, Selected = r.Selected };
于 2012-11-29T11:17:48.590 に答える