Продолжается подписка на наши издания! Вы не забыли подписаться?

LINQ to Entities vs. LINQ to SQL – что когда использовать?

Автор: Кевин Хоффман
Опубликовано: 04.07.2007

Недавно выпущена CTP-версия ADO.NET vNext, включающая ADO.NET Entity Framework. Хотя EF включает Entity SQL и много другого, меня больше интересуют такие части EF, как собственно EDM (Entity Data Model), Mapping Provider for ADO.NET, и более всего – LINQ to Entities.

LINQ to Entities позволяет писать C# LINQ-запросы к концептуальной модели данных. У меня не хватает слов, чтобы рассказать, насколько полезна возможность обращаться с запросом к концептуальной объектной модели, а не к схеме БД. Но у многих возникает вопрос – нужно ли использовать Entity Framework, или можно обойтись LINQ to SQL (ранее известным как DLINQ). В следующей таблице сравниваются возможности (на самом деле их куда больше, чем я включил в эту маленькую таблицу, но мне она, по крайней мере, облегчила принятие решений) обеих систем. Нужно понять, что LINQ to Entities – это надмножество LINQ to SQL. Если создаваемые вами в EDM сущности хранятся в БД SQL Server 2005, LINQ to Entities (далее для краткости L2E) будет динамически создавать SQL-выражения, которые свяжут модель сущностей с экземпляром БД и вернут результаты вашему коду.

LINQ to SQL LINQ to Entities
Поддержка языковых расширений + +
Интеграция запросов к БД в язык программирования + +
Многие-ко-многим (трехстороннее Join/Payload отношение) - -
Многие-ко-многим - +
Хранимые процедуры + -
Наследование сущностей - +
Сбор сущности из нескольких таблиц - +
Управление иденичностью + +

Поэтому вместо обсуждения областей, в которых L2SQL и L2E схожи, я собираюсь рассмотреть те точки, в которых они расходятся.

Первая – это объектная модель. Когда вы используете SQLmetal и DLINQ для создания объектной модели по схеме БД, вы берете эту схему и сразу создаете классы, представляющие эту схему. Эти классы снабжены атрибутами, сообщающими DLINQ, как связываться с БД. Если нужно изменить объектную модель, это нужно делать непосредственно в сгенерированных классах. Если изменяется схема БД, следует либо исправить сгенерированные классы, либо заново запустить SQLmetal. Entity Framework предоставляет слой абстракции: вы определяете концептуальную объектную модель, определяете XML-схему БД, а затем задаете логическое соответствие концептуальной объектной модели и схемы БД. Используя эту модель, вы очень хорошо изолированы от изменений БД. Большинство изменений БД могут быть спокойно поглощены схемой и ее отображением без необходимости изменения модели – благодаря этому вам не понадобится проводить рефакторинг и перестройку частей проекта, используемых по всему приложению.

Второе значительное различие становится возможным благодаря первому. Мощь слоя абстракции, обеспечиваемая Entity Framework, дает возможности наследования и композиции сущностей. Это значит, что можно создать сущность, составленную из колонок различных таблиц, не привлекая сложной логики объединений (join).

На композиции сущностей основывается наследование сущностей. Оно позволяет создавать сущности-наследники других сущностей. Например, можно создать в приложении сущность VideoGame. Есть много разных видов видеоигр, но вещи типа:

...... WHERE gm.GmType = 402 ....

выглядят не очень объектно-ориентированно. Многие программисты ежатся, глядя на такое (а если вы не ежитесь, вам должно быть стыдно!). Что нам на самом деле нужно, так нечто вроде:

var ps2Games = from game in AllGames 
  where game is Playstation2Game 
  orderby game.Rating 
  select game;

Вот этот код я могу читать, проводить его рефакторинг, поддерживать, и мне не нужно дергать автора кода в попытках выяснить, что он имел в виду. И при этом он дает ту же производительность, что и исходный T-SQL-запрос. Используя наследование сущностей и conditional properties, вы можете создавать классы, откликающиеся на знакомое по ООП ключевое слово is, но по-прежнему выполняющие все тот же зависящий от схемы запрос gm.GmType = 402 к базе данных.

Подводя итог, вот мои советы:

Вкратце, ADO.NET vNext и Entity Framework – это замечательные новинки, но есть несколько случаев, когда лучше потратить время на что-нибудь другое.

Спасибо Pablo из команды ADO.NET за выяснение, что LINQ to Entities на самом деле не использует то, что мы называли DLINQ, для генерации динамических SQL-выражений для отображения Entity Model на схему БД, это делает особый совместно используемый движок.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.

Copyright © 1994-2016 ООО "К-Пресс"