Разве Linq to SQL не упускает смысл? Разве ORM-картографы (SubSonic и т. Д.) Не являются оптимальными решениями? - PullRequest
69 голосов
/ 19 января 2009

Мне бы хотелось, чтобы сообщество приняло некоторые мысли о Linq to Sql и других средствах отображения ORM.

Мне нравится Linq to Sql и идея выражать логику доступа к данным (или операциям CRUD в целом) на вашем родном языке разработки, а не иметь дело с "несоответствием импеданса" между C # и SQL. Например, чтобы вернуть ObjectDataSource-совместимый список экземпляров Event для бизнес-уровня, мы используем:

return db.Events.Select(c => new EventData() { EventID = c.EventID, Title = c.Title })

Если бы я реализовал это с использованием старых конструкций SQL-to-C #, мне пришлось бы создать класс Command, добавить параметр EventID (используя строку для описания аргумента "@EventID"), добавить запрос SQL введите строку в класс Command, выполните команду и затем используйте (cast-type) nwReader ["FieldName"], чтобы получить каждое возвращенное значение поля и назначить его члену вновь созданного экземпляра моего класса EventData (yuck).

Итак, , что - вот почему людям нравится Linq / SubSonic / и т.д. и я согласен.

Однако на более широкой картине я вижу ряд вещей, которые не верны. Я чувствую, что Microsoft также видит что-то не так, и именно поэтому они убивают Linq для SQL и пытаются перевести людей в Linq для Entities. Только я думаю, что Microsoft удваивает ставку из-за плохой ставки.

Так, что не так?

Проблема в том, что есть астронавтов архитектуры , особенно в Microsoft, которые смотрят на Linq to Sql и понимают, что это не настоящий инструмент управления данными: есть еще много вещей, которые вы не можете легко сделать из Комфортно в C # и они стремятся исправить это. Вы видите это в амбициях Linq to Entities, сообщениях в блоге о революционной природе Linq и даже в LinqPad вызов .

И проблема с в том, что заключается в том, что он предполагает, что SQL является проблемой. То есть, чтобы уменьшить легкий дискомфорт (несоответствие импеданса между SQL и C #), Microsoft предложила эквивалент скафандра (полная изоляция), когда пластырь (Linq to SQL или что-то подобное) вполне подойдет.

Насколько я вижу, разработчики достаточно умны, чтобы освоить реляционную модель и затем разумно применять ее в своих усилиях по разработке. На самом деле, я бы пошел еще дальше и сказал, что Linq to SQL, SubSonic и т. Д. уже слишком сложны: кривая обучения не так уж сильно отличается от освоения самого SQL. Поскольку в обозримом будущем разработчики должны осваивать SQL и реляционную модель, мы столкнулись с изучением двух языков запросов / CRUD. Хуже того, Linq часто сложно протестировать (у вас нет окна запроса), он удаляет нас на один уровень из реальной работы, которую мы выполняем (генерирует SQL), и имеет очень неуклюжую поддержку (в лучшем случае) для таких конструкций SQL, как Обработка даты (например, DateDiff), «Имея» и даже «Группировать по».

Какая альтернатива? Лично мне не нужна другая модель доступа к данным, как Linq to Entities. Я бы предпочел просто открыть окно в Visual Studio, ввести и проверить мой SQL, а затем нажать кнопку, чтобы сгенерировать или дополнить класс C # для инкапсуляции вызова. Поскольку вы уже знаете SQL, не хотели бы вы просто ввести что-то вроде этого:

Select EventID, Title From Events Where Location=@Location

и в результате получается класс EventData, который A) содержит поля EventID и Title в качестве свойств, а B) имеет метод фабрики, который принимает строку «Location» в качестве аргумента и генерирует список ? Вы должны тщательно продумать объектную модель (приведенный выше пример, очевидно, не справляется с этим), но фундаментальный подход, основанный на использовании SQL и устранении несоответствия импедансов, очень меня привлекает.

Вопрос: я ошибаюсь? Должна ли Microsoft переписать инфраструктуру SQL, чтобы вам больше не приходилось изучать управление SQL / реляционными данными? Могут ли переписать инфраструктуру SQL таким образом? Или вы думаете, что очень тонкий слой поверх SQL, чтобы избавить вас от необходимости настройки параметров и доступа к полям данных, вполне достаточен?

Обновление Я хотел продвинуть две ссылки на вершину, потому что я думаю, что они отражают важные аспекты того, что я преследую. Во-первых, CodeMonkey указывает на статью под названием «Вьетнам компьютерных наук». Требуется некоторое время, чтобы начать, но это очень интересное чтение. Во-вторых, AnSGri указывает на одну из наиболее выдающихся пьес Джоэла Спольски: Закон Утечки Абстракций . Это не совсем по теме, но это близко и является отличным чтением.

Обновление 2: я дал «ответ» ocdecio, хотя здесь есть много хороших ответов, и выбор «правильного» ответа является чисто субъективным. В этом случае его ответ в квадрате с тем, что я считаю действительно лучшей практикой, учитывая современное состояние технологий. Однако это та область, в которой я полностью ожидаю развития, поэтому все может измениться. Я хотел бы поблагодарить всех, кто внес свой вклад, я проголосовал за всех, кто, я думаю, дал вдумчивый ответ.

Ответы [ 24 ]

5 голосов
/ 20 января 2009

Будучи самим автором проекта ORM, я должен признать, что мой ответ на такой вопрос может быть немного предвзятым. Я уже выработал некоторые собственные мысли об ответе до того, как прочел вопрос, поэтому я уже немного привязан.

Я скажу, что моя причина разработки ORM была не из-за "несоответствия импедансов" между SQL и императивным программированием, а скорее для того, чтобы стать независимым от платформы базы данных. Прежняя проблема необходимости писать больше кода для управления постоянством - это небольшое препятствие, которое легко решается, если вы работаете только с одним поставщиком баз данных. Стать независимым от платформы баз данных - гораздо более сложная проблема, и imo оказывает гораздо большее влияние на прибыльность вашего бизнеса, если предположить, что вы, как и я, планируете продавать программное обеспечение другим людям (а не просто использовать его дома).

Когда я начал работать над своими инструментами ORM несколько лет назад, концепция была непрактичной на моем любимом языке, большинство людей, с которыми я общался, не понимали, почему я над этим работаю, и некоторые уважаемые в сообществе голоса имели столько же как написано в торговых журналах о том, что то, что я уже сделал, было не только невозможно, но и нежелательно. Были приведены некоторые из тех же причин - это слишком сложно, это ограничивает и добавляет накладные расходы. Сегодня в том же сообществе есть по крайней мере три популярных инструмента для абстрагирования базы данных (хотя есть некоторые споры об определении термина ORM). Причина, по которой я упоминаю об этом, заключается в том, что когда я начал работать над этими инструментами, первоначальные возражения имели гораздо больший вес, чем сейчас. Основная технология, как аппаратное, так и программное обеспечение, изменилась за прошедшие годы, чтобы сделать эти инструменты намного более практичными в долгосрочной перспективе. Моя тенденция состоит в том, чтобы попытаться взглянуть на программное обеспечение в долгосрочной перспективе и поработать над решениями, которые, возможно, еще не совсем практичны, но скоро станут практичными. Поэтому, учитывая, что я не буду считать LINQ to Entities хорошим решением для определенных проблем.

Я также предпочитаю больше вариантов, чем меньше. Поэтому, хотя я могу поддержать идею разработки LINQ to Entities, я менее склонен поддерживать уничтожение LINQ to SQL просто потому, что стала доступна LINQ to Entities. Объекты отлично подходят для того, чтобы делать то, что делают объекты, в этом нет никаких сомнений ... По моему (опять-таки предвзятому) мнению, проблема возникает в том, что люди рассматривают любой данный инструмент или парадигму программного обеспечения как "волшебную пулю" и хотят настаивать на том, чтобы все должно быть так. Хорошо известно, что реляционная база данных очень хорошо справляется с некоторыми другими задачами, хорошим примером является отчетность. Так что, по моему мнению, это своего рода выстрел в ногу, чтобы настаивать на том, что все должно быть сущностями, потому что тогда вы заставляете себя использовать неэффективный инструмент для работы. Так что, в частности, для отчетов, избавление от LINQ to SQL и использование только LINQ to Entities хотя бы на поверхности звучит для меня как антишаблон инверсия абстракции .

Итак, я думаю, что краткий обзор моего ответа таков: используйте молоток, если ваша проблема - гвоздь, - используйте отвертку, если ваша проблема - винт.

4 голосов
/ 19 января 2009

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

Преимущества - быстрая разработка, запросы, которые соответствуют языку, а не экранированным строкам и т. Д., Часто перевешивают недостатки. Если производительность является проблемой, вы можете оптимизировать позже.

Я не думаю, что «не нужно знать SQL» является фактором. Любой достойный разработчик должен знать SQL в какой-то момент своей разработки. Идея уровня абстракции базы данных состоит в том, чтобы исключить усилия по генерации шаблонного кода для запросов к базе данных.

Действительно, в нашей системе на Java я создал утилиту генерации кода, которая брала аннотированные классы и генерировала полный CRUD API, а также обрабатывала все те изворотливые вещи, которые вы выбираете с течением времени. Гораздо проще создать свою модель и аннотировать ее, чем писать через DAO. Масштабируйте такой инструмент, и вы получите LINQ, Hibernate или множество других решений ORM DB.

4 голосов
/ 19 января 2009

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

Я не большой поклонник встроенного программирования баз данных (независимо от того, является ли код sql ручным или машинным). Я считаю, что база данных - это основа приложения, и что стоит потратить время на ручное кодирование хранимых процедур.

Тем не менее, я заинтригован концепцией OODBMS и надеюсь, что когда-нибудь я начну работать над некоторыми из них в производственной среде.

4 голосов
/ 25 января 2009

Если вы хотите, чтобы база данных работала по мере ее масштабирования, она должна быть спроектирована и нормализована в соответствии с лучшими практиками реляционной модели базы данных.

Если вы позволите объектной модели и ORM определять вашу модель данных, вы просто получите плохую модель данных, которая не нормализована и / или содержит артефакты из объектной модели.

1 таблица = 1 класс - плохая идея.

Для начала никогда не имейте классов, которые представляют собой таблицы ссылок "многие ко многим" или "многие к одному". Они соответствуют дочерним коллекциям в объектной модели - сами ссылки не являются объектами.

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

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

3 голосов
/ 19 января 2009

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

3 голосов
/ 19 января 2009

Я думаю, что реальное решение, в котором они нуждались, было чем-то большим, чем SQL-литерал. VB.Net 9.0 поддерживает XML Literals , которые позволяют вам писать XML прямо в вашем коде и гарантировать, что он проверен и соответствует DTD. Аналогичным приятным свойством могут быть литералы SQL, которые позволяют писать встроенный код SQL в коде .Net и проверять его в IDE. Для проверки информации в базе данных потребуется какая-то архитектура плагинов, но ее можно легко написать для популярных механизмов баз данных. Это дало бы то, что я считаю реальным решением проблемы, которую они пытались решить, не прибегая к неоптимальным решениям.

3 голосов
/ 20 января 2009

Codemonkey делает очень хорошее замечание: хранимые процедуры предлагают уровень абстракции, который удовлетворяет некоторым требованиям более сложных моделей ORM. На первый взгляд это не интуитивно понятно, но я могу вспомнить пример прямо из моего собственного кода. У меня есть sproc "check-in", который затрагивает почти дюжину таблиц (кому принадлежит этот идентификатор? Есть ли у них членство? Есть ли какие-либо сообщения? Они получают очки за эту регистрацию? И т. *

Моделирование этого в C # - независимо от того, насколько сложна модель данных - никогда не будет хорошей идеей, поскольку для этого потребуется много поездок «по проводам» для проверки данных и обновления различных таблиц. Хотя верно, что вы можете обрабатывать sprocs в Linq или других ORMS, все, что мне нужно - это класс-оболочка, который позволяет мне вызывать sproc со стандартными параметрами C #. На самом деле, это было настолько острой необходимостью, что я написал генератор кода на T-SQL для создания таких оболочек.

3 голосов
/ 19 января 2009

Мне не нравится ни одно из существующих решений - но я предпочитаю больше вариантов, чем меньше вариантов; -)

я давно использовал OODBMS в проекте, который был наиболее близок к правильному (к сожалению, у продукта были некоторые отвратительные ошибки и ужасная техническая поддержка) - постоянство объектов было в значительной степени невидимым , обработанным за кулисами (через генератор кода препроцессора) и управляется очень простыми методами Update, Delete и Find и простыми контейнерами.

Мне бы очень хотелось увидеть это (и, возможно, какая-то объектно-объектная модель уже делает это хорошо) снова с OCL (Object Constraint Language) в качестве собственного языка многообъектных запросов

2 голосов
/ 19 января 2009

Я должен согласиться с тем, что всплеск инструментов ORM в значительной степени связан с раздражением написания SQL, имеющим дело с любым драйвером БД, который вам нужно использовать, внутренним абстрагированием между БД (Oracle против SQL Server и против любого другого для повторного использования кода), и преобразование типов данных.

Идеальное решение? определенно нет! Тем не менее, я думаю, что это итерация в процессе лучшего слияния приложения с хранилищем данных. В конце концов, в большинстве случаев наличие БД без доступа к приложению, написанному на любом языке, практически бесполезно. (действительно ли вы когда-нибудь просто установите Oracle и ожидаете, что все сотрудники будут работать в SQLPlus напрямую?)

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

В частности, для .NET я бы предпочел вместо Linq встроенный способ сопоставить определение класса базовому источнику данных с базовым хранилищем данных, а вся сантехника просто работает.

Другими словами, я мог бы просто сказать "Employee.Name = 'Rally25rs';" и свойство объекта изменится, и под ним оно сохранится в самом хранилище данных. Просто полностью отказывайтесь от SQL вместо того, чтобы идти на 1/2 пути, как сейчас делает Linq to SQL.

Конечно, подобное решение вызывает проблемы с производительностью, обработкой транзакций и т. Д.

Может быть, вся концепция языка программирования и реляционной базы данных должна быть переосмыслена и перестроена? По своей сути они являются совершенно отдельными и несвязными сущностями. Возможно, пришло время просто отказаться от «реляционной базы данных с поддержкой SQL» и построить следующую вещь, когда выполнение строки кода будет напрямую работать с базой данных.

1 голос
/ 02 февраля 2010

Я только что открыл этот вопрос. Я предполагаю, что это в значительной степени уже разыграно, но я все равно добавлю свои два цента ...

Я хочу писать код только для вещей, которые не очевидны.

Код CRUD очевиден. Я не хочу это писать. Поэтому ORM - хорошая идея.

Это не означает, что у ORM нет проблем, но проблемы связаны с выполнением, а не с намерением. По мере взросления ORM проблемы будут уменьшаться, и прирост производительности, уже доступный для простых сценариев, будет в конечном итоге распространяться и на сложные сценарии.

LINQ также хорошая идея. Другие упомянули ряд преимуществ, но все, что мне нужно сделать, это подумать о том, когда я впервые попытался сделать разворот в LINQ, где я заранее не знал количество столбцов. Или когда я впервые понял, что мне не нужно создавать новый DataView каждый раз, когда я хочу что-то отсортировать или отфильтровать. LINQ дает мне возможность делать все, что я хочу делать с данными в C #, вместо того, чтобы выяснять, как распределить работу между SQL и C #.

Итак, да, ORM, LINQ и другие появляющиеся технологии являются субоптимальными решениями, но они не упускают из виду и не будут вечно неоптимальными.

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