Зачем использовать LINQ Join в простых отношениях один-много? - PullRequest
19 голосов
/ 29 августа 2011

Я использую LINQ to SQL и Entity Framework в течение нескольких лет, и я всегда сопоставлял свои связи с базой данных, чтобы генерировать соответствующие свойства навигации.И я всегда использую свойства навигации.

Я что-то упускаю?

Если у меня есть отношение типа Category->Products один-много, я бы использовал

var redProducts = context.Category.Single(c => c.Name = "red").Products;

Я регулярно вижу людей, выполняющих ручные объединения, по всему этому сайту, в проектах онлайн и на различных других веб-сайтах.

var employer = from category in context.Categories
               join product in context.Products
               on category.CategoryId equals product.CategoryId
               where category.Name == "red"
               select product;

Итак - почему?Каковы преимущества использования этого Join синтаксиса?

Ответы [ 3 ]

9 голосов
/ 29 августа 2011

Обычно это ошибка.

@ Джордж прав, что ваши два примера функционально отличаются друг от друга так, что не имеют ничего общего с join против не- join,тем не мение.Но вы могли бы так же легко написать:

var redProducts = context.Category
                         .Where(c => c.Name == "red")
                         .SelectMany(c => c.Products);

..., который функционально идентичен (но превосходит по POV для удобства чтения и обслуживания) вашему примеру join.

4 голосов
/ 29 августа 2011

Это может быть результатом переноса старого кода на linq2sql.

Однако два фрагмента кода не являются функционально равными.

Single вызовет исключение, а join приведет кпустая коллекция в случае отсутствия записи.

Таким образом, равный код без использования объединений будет:

from c in context.Categories where c.Name == "red" from p in c.Products select p;

или

context.Categories.Where(c=>c.Name == "red").SelectMany(c=>c.Products);
3 голосов
/ 29 августа 2011

Объединения, вероятно, более распространены для людей, исходящих из реляционного мышления, чем объектно-ориентированного.Если вы думаете о своем проблемном пространстве с объектно-ориентированной точки зрения, гораздо более естественно работать с отношениями, где вы можете разбить навигацию: Employee.Customers.Orders.OrderItems.OrderItem, чем иметь дело с кучей объединений.Оригинальный технический документ ADO.vNext проделал хорошую работу по обсуждению преимуществ использования модели и ассоциаций, а не объединений для работы с вашими концептуальными моделями.К сожалению, на данный момент я не могу найти этот документ.

Для меня объединения лучше всего использовать, когда у вас нет естественных ассоциаций между сущностями.Например, если вы пытаетесь объединить элементы на неестественных ключах (например, объединение на Customer.State и Shipping.State), вы должны использовать синтаксис объединения (или SelectMany), а не создавать ассоциации между вашими сущностями в этом случае.

Следует помнить одну вещь: синтаксис объединения и использование ассоциаций могут привести к различиям в типах соединений, генерируемых поставщиком.Как правило, объединение преобразуется во внутреннее объединение и исключает элементы, в которых нет совпадения с обеих сторон объединения.Чтобы выполнить (левое) внешнее объединение, вы используете расширение DefaultIfEmpty.

Перемещение по ассоциациям в отношениях 1-0 .. *, с другой стороны, обычно переводится в правые внешние соединения, потому что дочерняя коллекция может быть законно пустой, и вы захотите включить родителя, даже если ребенок не сделал этого.не существует.Вы бы использовали !Any() для отлова дел, в которых нет дочерних записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...