使用“from”不止一次相当于加入?

时间:2012-04-10 20:05:21

标签: c# linq

我遇到了以下代码,并且不知道在此代码中来自两次意味着什么。这是否意味着书籍和CSBook之间存在联系?

List<Product> Books = new List<Product>();   
            List<Product> CSBooks = new List<Product>();
            var AllBooks = from Bk in Books
                           from CsBk in CSBooks
                           where Bk != CsBk
                           select new[] { Bk, CsBk };

3 个答案:

答案 0 :(得分:13)

这就像是一个加入。当你说:

from customer in customers
join order in orders on customer.Id equals order.CustomerId
select whatever

本质上是一种更有效的写作方式:

from customer in customers
from order in orders
where customer.Id == order.CustomerId
select whatever

你明白为什么吗?第一个说“嘿查询处理器,客户和订单有一个特殊的关系,由客户的ID和订单中存储的客户ID的相等性定义”。第二个只是说“给我笛卡尔产品 - 所有可能的客户和订单组合 - 然后过滤掉那些没有任何意义的产品”。它们具有相同的效果,但前者效率更高。

但是,您可以使用多个“from”子句来执行比Cartesian产品更有趣的事情。假设客户可以有多个地址:

from customer in customers
from address in customer.Addresses
select address

多个from子句实际上是“选择多个”。也就是说,它们采用序列,而是从第一个序列的每个项目生成序列的方法< / em>,将所有结果序列合并在一起

“选择多人”很简单但功能非常强大;我们已经看到你可以使用“选择多个”来进行(慢速但正确的)连接操作。事实上,如果你足够聪明并且不介意浪费大量的时间和记忆,你可以使用select many来制作每个可能的查询。例如:

from customer in customers
where customer.City == "London"
select customer

可以写成没有像这样的“where”:

from customer in customers
from c in (customer.City == "London" ? 
               new Customer[] {customer} : 
               new Customer[] { } )
select c;

你这样做会很疯狂,但wherejoin实际上是不必要的 - 它们只是更快,更短,更有效的方式来编写选择许多

答案 1 :(得分:3)

from两次是交叉产品。这是BooksCSBooks

的所有组合

答案 2 :(得分:2)

它更像是一个连接的反面。我认为其结果实际上是笛卡尔积。也就是说,由于!=,它将在第二组的每个元素上连接第一组的每个元素,该元素不等于第一个元素。