Синтаксис перекрестного соединения в Entity Framework / IQueryable

Я пытаюсь углубить свое образование о пользовательских провайдерах IQueryable и деревьях выражений. Меня интересует пользовательский анализ перекрестного соединения (а именно SelectMany), и я пытаюсь понять, что именно делает EF, когда обрабатывает это:

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

Предположительно, EF может обрабатывать перекрестные соединения, хотя синтаксис в этой ссылке мне не подходит. Затем я нашел ссылку с названием " Cross Product Queries" для EF. Синтаксис выглядит "правильным", но сама статья говорит о том, что это обычные внутренние соединения, а не перекрестные соединения.

Действительно, приведенный выше фрагмент кода взят из этой последней статьи - и мне остается только задуматься, говорит ли EF: "Я знаю, как связаны эти две сущности, поэтому я автоматически сформирую внутреннее соединение".

Какова реальная история с EF и этим предполагаемым образцом "перекрестного соединения"?

сноска

Когда я пытаюсь создать свой собственный поставщик LINQ для IQueryable, цель обучения, которую я для себя поставил, состоит в том, чтобы создать собственный контекст запроса для приведенного выше фрагмента кода, чтобы при вызове ToList() вызывался запрос:

  1. Console.WriteLine() автоматически запускается, который печатает "Это перекрестное соединение:Customer а также Order
  2. == оператор волшебным образом превращается в != до того, как запрос полностью интерпретируется (возможно, ExpressionVisitor, не уверен).

Если кто-то знает статьи или имеет фрагменты кода, которые бы ускорили мою образовательную цель, пожалуйста, поделитесь!:)

1 ответ

Решение

Посмотрите внимательно на синтаксис:

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 синтаксис.

Другие вопросы по тегам