c# sql asp.net linq cartesian-product

c# - ¿Hay una buena forma LINQ para hacer un producto cartesiano?



sql asp.net (3)

Si entiendo la pregunta, quiere el producto cartesiano de n conjuntos de cachorros.

Es fácil obtener el producto cartesiano si sabe en tiempo de compilación cuántos conjuntos hay:

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

Supongamos que dog1 tiene cachorros p11, p12, dog2 tiene cachorro p21, y dog3 tiene cachorros p31, p32. Esto te da

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

Donde cada fila es de tipo anónimo Si no sabe en tiempo de compilación cuántos conjuntos hay, puede hacerlo con un poco más de trabajo. Ver mi artículo sobre el tema:

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

y esta pregunta de StackOverflow:

Generando todas las combinaciones posibles

Una vez que tenga el método CartesianProduct<T> , puede decir

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

Llegar

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

Donde cada fila es una secuencia de cachorros.

¿Tener sentido?

Tengo una estructura de clases así:

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

Hay una persona Él tiene 1..n perros. Cada perro tiene 1..n cachorros.

Quiero una lista de todas las posibles combinaciones de cachorros, tomando 1 cachorro de cada perro. P.ej:

perro 1 cachorro A, perro 2 cachorro Un perro 1 cachorro A, perro 2 cachorro B perro 1 cachorro B, perro 2 cachorro Un perro 1 cachorro B, perro 2 cachorro B

Si estuviera en tablas sql, haría algo como lo siguiente para ''multiplicar'' las tablas:

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

¿Hay alguna forma linq-ish de hacer esto?

Muchas gracias


Si quieres todas las combinaciones posibles de perro y cachorro, harías una combinación cruzada:

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


dogs.Join (cachorros, () => verdadero, () => verdadero, (uno, dos) => nuevo Tuple (uno, dos));

Puede hacer una unión normal, pero los selectores devuelven el mismo valor, porque quiero que todas las combinaciones sean válidas. Cuando combine, coloque ambos en una sola tupla (o una estructura de datos diferente de su elección).

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

Esto debería hacer un producto cartesiano.