Синтаксис перекрестного соединения в 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() вызывался запрос:
- Console.WriteLine() автоматически запускается, который печатает "Это перекрестное соединение:
Customer
а такжеOrder
==
оператор волшебным образом превращается в!=
до того, как запрос полностью интерпретируется (возможно, 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
синтаксис.