このリストは ID とサムネイルを返します。元。List<PersonPicture>
このリストにList<Person>
は、「画像」という名前のプロパティがあります。とにかく、この2つのプロパティをマージしてList<PersonPicture>
、「picture」という名前のプロパティに追加し、IDを介してこれをベースにすることはできますか?
どんな助けでも大歓迎です。
このリストは ID とサムネイルを返します。元。List<PersonPicture>
このリストにList<Person>
は、「画像」という名前のプロパティがあります。とにかく、この2つのプロパティをマージしてList<PersonPicture>
、「picture」という名前のプロパティに追加し、IDを介してこれをベースにすることはできますか?
どんな助けでも大歓迎です。
LINQ は、このような既存のコレクションを変更するようには設計されていませんが、それは可能です。
foreach (tup in people
.Join(
picture,
person => person.ID,
picture => picture.ID,
Tuple.Create
))
{
tup.Item1.Picture = tup.Item2;
}
編集: 人が複数の写真を持っている場合、これは予測できない結果になることに注意してください。この可能性はありますか?また、どのように対処する必要がありますか?
以下の例では、匿名オブジェクトを使用できます。
List<PersonPicture> pictures = LoadPictures();
List<Person> persons = LoadPersons();
var result = persons.Select(pers => new
{
Id = pers.Id,
Name = pers.Name,
Picture = pictures.Where(pic => pic.PersId == pers.Id)
.FirstOrDefault()
.Thumbnail
};
別の解決策は、結合を使用することです。
var result = persons.Join(pictures,
pers => pers.Id,
pic => pic.PersId,
(pers, pic) => {
return new
{
Id = pers.Id,
Name = pers.Name,
Picture = pic.Thumbnail
};
});
共有キー (ID) に基づいて 2 つのリストを結合します。
基本的に、Join
LINQ で演算子を使用して、同じ ID に一致する と のPerson
ペアを検索します。PersonPicture
persons.Join(pictures, // join these two lists
person => person.Id, // extract key from person
personPicture => personPicture.PersonId, // extract key from picture
(person, personPicture) => ??? // do something with each matching pair
ここで直面する問題は、一致する各ペアをどうするかということです。Join
一致するペアを受け取り、他の何かを返すデリゲートを提供できます。結合操作の結果は、一致する各ペアから生成された「何か他のもの」のリストになります。
あなたの問題は、各ペアを取り、それを使って何かをしたいということです。具体的には、PersonPicture
オブジェクトからオブジェクトに画像をコピーしたいということですPerson
。LINQ はデータを検索することがすべてであり、データを変更することではないため、これは簡単ではありません。
これには 2 つの方法があります。1 つは、各ペアから一時的なオブジェクトを作成し、それを反復処理して自分のことを行うことです。
var pairs = persons.Join(pictures,
person => person.Id,
personPicture => personPicture.PersonId,
(person, personPicture) => new { person, personPicture };
foreach (var pair in pairs)
pair.person.Picture = pair.personPicture.Thumbnail;
(別の回答で提案されているように、一時オブジェクトの代わりにタプルを使用できます)。
これは機能しますが、一時オブジェクト (匿名オブジェクトまたはタプル) のために扱いにくいようです。
別の方法として、デリゲート内で割り当てを行い、PersonPicture オブジェクトの処理が完了しているため、Person オブジェクト自体を返すこともできます。
var personsWithPicturesPopulated = persons.Join(pictures,
person => person.Id,
personPicture => personPicture.PersonId,
(person, personPicture) => {
person.Picture = personPicture.Thumbnail;
return person;
});
これには、リストで一致を見つけた人物のリストが表示され、一致しない人物はpersonPictures
省略されるという追加のボーナスがあります。これがまさに必要なものである場合もあります (そうでない場合もあります。その場合は、結合の結果を破棄できます)。