2

我正在尝试加深对 IQueryable 自定义提供程序和表达式树的了解。我对自定义解析交叉连接(即 SelectMany)感兴趣,我试图了解这是否正是 EF 在处理此问题时所做的事情:

var infoQuery =
    from cust in db.Customers
    from ord in cust.Orders
    where cust.City == "London"
    select ord;

据称EF 可以处理 cross joins,尽管该链接中的语法对我来说看起来不正确。然后我为 EF找到了一个标题为“ Cross Product Queries ”的链接。语法看起来“正确”,但文章本身就好像这些是正常的内部连接而不是交叉连接。

事实上,上面的代码片段来自上一篇文章——这让我想知道 EF 是否只是说“我知道这两个实体是如何相关的,所以我将自动形成内部连接”。

EF 和这个所谓的“交叉连接”样本的真实故事是什么?

脚注

当我尝试构建自己的 IQueryable LINQ 提供程序时,我为自己设定的教育目标是为上面的代码片段创建自己的查询上下文,以便在查询上调用 ToList() 时:

  1. 一个 Console.WriteLine() 被自动触发,打印“这是一个交叉连接:CustomerOrder
  2. 在查询被完全解释之前,运算符被神奇地转换为 a (可能是ExpressionVisitor ==不确定)。!=

如果有人知道可以加快我的教育目标的文章或代码片段,请分享!:)

4

1 回答 1

2

仔细看语法:

from cust in db.Customers
from ord in cust.Orders       // cust.
select ...

因为cust.Orders这是一个常规的内部连接。它甚至是进行连接的首选方式,因为它比常规的连接语句要简洁得多。

我不明白这篇“跨产品查询”文章的标题。首先,因为据我所知,“叉积”适用于三维向量而不是关系代数。其次,因为示例中没有单个交叉连接,只有内部连接。也许他们想说的是上面的语法看起来像一个交叉连接?但事实并非如此,所以在标题中如此突出地使用这个词只会让人感到困惑。

此代码段

from cust in db.Customers
from ord in db.Orders         // db.
select ...

是真正的交叉连接(或笛卡尔积)。如果有n客户和m订单,则结果集包含 n * m 行。对订单和客户几乎没有用,但在两个序列中获取元素的所有组合可能很有用。如果您想加入但在加入中还需要第二个条件,则此构造也很有用,例如

from cust in db.Customers
from ord in db.Orders
where cust.CustomerId == ord.CustomerId && ord.OrderDate > DateTime.Today

这有效地把它变成了一个内部连接。也许不是最好的例子,但在某些情况下这会派上用场。join - on - equals语法中不支持它。

于 2013-04-25T07:44:59.710 回答