私はそのようなクラス構造を持っています:
Person
Dogs (dog 1, dog 2, etc)
Puppies (puppy A, puppy B, etc)
一人です。彼は1..n匹の犬を飼っています。各犬には1..nの子犬がいます。
各犬から1匹の子犬を取り、子犬の可能なすべての組み合わせのリストが必要です。例えば:
犬1子犬A、犬2子犬A犬1子犬A、犬2子犬B犬1子犬B、犬2子犬A犬1子犬B、犬2子犬B
それがsqlテーブルにあった場合、次のようにテーブルを「乗算」します。
select * from puppies a, puppies b where a.parent='dog1' and b.parent='dog2'
このちょっとしたことをするためにいくつかのlinq風の方法はありますか???
本当にありがとう
私が質問を理解していれば、n個の子犬のデカルト積が必要です。
コンパイル時にセットの数がわかっている場合は、デカルト積を簡単に取得できます。
from p1 in dog1.Puppies
from p2 in dog2.Puppies
from p3 in dog3.Puppies
select new {p1, p2, p3};
Dog1に子犬p11、p12、dog2に子犬p21、dog3に子犬p31、p32があるとします。これはあなたに与えます
{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}
各行は匿名型です。コンパイル時にセットがいくつあるかわからない場合は、少し作業を増やして行うことができます。主題に関する私の記事を参照してください:
http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
そしてこのStackOverflowの質問:
メソッドを取得したらCartesianProduct<T>
その後、次のように言うことができます
CartesianProduct(from dog in person.Dogs select dog.Puppies)
取得するため
{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}
ここで、各行は子犬のシーケンスです。
理にかなっていますか?
dogs.Join(puppies、()=> true、()=> true、(one、two)=> new Tuple(one、two));
通常の結合を実行できますが、すべての組み合わせを有効にしたいため、セレクターはどちらも同じ値を返します。組み合わせるときは、両方を1つのタプル(または選択した別のデータ構造)に入れます。
leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));
これはデカルト積を実行するはずです。
犬と子犬のすべての可能な組み合わせが必要な場合は、クロス結合を実行します。
from dog in Dogs
from puppy in Puppies
select new
{
Dog = dog,
Puppy = puppy
}