Existe uma boa maneira LINQ de fazer um produto cartesiano?

Eu tenho uma estrutura de classs assim:

Person Dogs (dog 1, dog 2, etc) Puppies (puppy A, puppy B, etc) 

Existe uma pessoa. Ele tem 1. n cães. Cada cão tem 1.n cachorros.

Eu quero uma lista de todas as possíveis combinações de filhotes, levando um filhote de cachorro de cada cachorro. Por exemplo:

cachorro 1 cachorro A, cachorro 2 cachorro Um cachorro 1 cachorro A, cachorro 2 cachorro B cachorro 1 cachorro B, cachorro 2 cachorro Um cachorro 1 cachorro B, cachorro 2 cachorro B

Se fosse em tabelas sql, eu faria algo como o seguinte para ‘multiplicar’ as tabelas:

 select * from puppies a, puppies b where a.parent='dog1' and b.parent='dog2' 

Existe alguma maneira linq-ish para fazer esse tipo de coisa ???

Muito obrigado

Se eu entendi a pergunta, você quer o Produto Cartesiano de n conjuntos de filhotes.

É fácil obter o produto cartesiano se você sabe em tempo de compilation quantos conjuntos existem:

 from p1 in dog1.Puppies from p2 in dog2.Puppies from p3 in dog3.Puppies select new {p1, p2, p3}; 

Suponha que dog1 tenha filhotes p11, p12, dog2 tenha filhote p21, e dog3 tenha filhotes p31, p32. Isso te dá

 {p11, p21, p31}, {p11, p21, p32}, {p12, p21, p31}, {p12, p21, p32} 

Onde cada linha é um tipo anônimo. Se você não sabe em tempo de compilation quantos conjuntos existem, você pode fazer isso com um pouco mais de trabalho. Veja meu artigo sobre o assunto:

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

e esta pergunta do StackOverflow:

Gerando todas as combinações possíveis

Depois de ter o método CartesianProduct então você pode dizer

 CartesianProduct(from dog in person.Dogs select dog.Puppies) 

para obter

 {p11, p21, p31}, {p11, p21, p32}, {p12, p21, p31}, {p12, p21, p32} 

Onde cada linha é uma seqüência de filhotes.

Faz sentido?

dogs.Join (filhotes de cachorro, () => verdadeiro, () => verdadeiro, (um, dois) => novo Tupla (um, dois));

Você pode fazer uma junit regular, mas os seletores estão retornando o mesmo valor, porque eu quero que todas as combinações sejam válidas. Ao combinar, coloque ambos em uma tupla (ou uma estrutura de dados diferente de sua escolha).

 leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r)); 

Isso deve fazer um produto cartesiano.

Se você quiser todas as combinações possíveis de cachorro e filhote, faça uma união cruzada:

 from dog in Dogs from puppy in Puppies select new { Dog = dog, Puppy = puppy }