Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多次使用“from”是否等同于拥有join?_C#_Linq - Fatal编程技术网

C# 多次使用“from”是否等同于拥有join?

C# 多次使用“from”是否等同于拥有join?,c#,linq,C#,Linq,我遇到了下面的代码,不知道在这段代码中有两次是什么意思。这是否意味着书籍和CSBooks之间存在连接 List<Product> Books = new List<Product>(); List<Product> CSBooks = new List<Product>(); var AllBooks = from Bk in Books f

我遇到了下面的代码,不知道在这段代码中有两次是什么意思。这是否意味着书籍和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 };

从两倍开始是叉积。这是Books和CSBooks的所有组合,更像是连接的反面。我认为结果实际上是笛卡尔积。也就是说,由于,它将第一个集合中的每个元素与第二个集合中不等于第一个元素的每个元素连接起来。

这类似于连接。当你说:

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
Multiple-from子句实际上是一个select-many。也就是说,它们获取一个序列,并从第一个序列的每个项目生成序列,然后将所有结果序列合并在一起

选择多是简单的,但非常强大;我们已经看到,您可以使用selectmany进行缓慢但正确的连接操作。事实上,如果您足够聪明并且不介意浪费大量时间和内存,您可以使用selectmany来进行所有可能的查询。例如:

from customer in customers
where customer.City == "London"
select customer
可以在没有类似以下位置的情况下编写:

from customer in customers
from c in (customer.City == "London" ? 
               new Customer[] {customer} : 
               new Customer[] { } )
select c;
这样做可能会让你发疯,但where和join实际上是不必要的——它们只是编写selectmany的更快、更短、更有效的方法