有没有一个很好的LINQ方法来做笛卡尔产品?

我有一个像这样的类结构:

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

有一个人 他有1..n条狗。 每只狗有1..n只小狗。

我想要一个所有可能的小狗组合的列表,每只狗取一只小狗。 例如:

狗1小狗A狗2小狗狗1小狗A狗2小狗B狗1小狗B狗2小狗狗1小狗B狗2小狗B

如果是在sql表中,我会做类似下面的“乘”表:

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

有没有一些linq-ish的方式来做这种事情?

非常感谢

如果我明白这个问题,你需要n套小狗的笛卡尔积

如果在编译时知道有多less个集合,那么获得笛卡尔积很容易:

 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} 

每行都是匿名types。 如果你不知道在编译时有多less套,你可以做更多的工作。 看到我关于这个问题的文章:

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));

您可以执行常规连接,但是select器都返回相同的值,因为我希望所有组合都是有效的。 合并时,将两者合并成一个元组(或您select的不同数据结构)。

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

这应该做笛卡尔产品。

如果你想要所有可能的狗和小狗的组合,你会做一个交叉连接:

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