6

我遇到了以下代码,不知道在这段代码中有两次是什么意思。这是否意味着 Books 和 CSBooks 之间存在连接?

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 };
4

3 回答 3

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”子句来做比笛卡尔积更花哨的事情。假设一个客户可以有多个地址:

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

多个from子句实际上是“select many”。 也就是说,它们采用一个序列,以及一种从第一个序列的每个项目制作序列的方法,并将所有结果序列合并在一起

“select many”很简单,但非常强大;我们已经看到您可以使用“选择多个”来进行(缓慢但正确的)连接操作。事实上,如果您足够聪明并且不介意浪费大量时间和内存,您可以使用 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;

这样做你会很疯狂,但where实际上join不必要的——它们只是更快、更短、更有效的编写选择多的方法。

于 2012-04-10T20:25:15.740 回答
3

from两次是叉积。这是Books和的所有组合CSBooks

于 2012-04-10T20:10:13.350 回答
2

它更像是连接的反面。我认为这样做的结果实际上是一个笛卡尔积。也就是说,由于!=,它会将第一个集合的每个元素连接到第二个集合的每个不等于第一个元素的元素上。

于 2012-04-10T20:10:47.380 回答