LINQ-to-SQL vs хранимые процедуры? [закрытый]

Я взглянул на сообщение "руководство для начинающих по LINQ" здесь, на StackOverflow (руководство для начинающих LINQ), но был следующий вопрос:

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

Итак, вопрос в следующем: для простых извлечений данных, какой подход лучше, LINQ-to-SQL или сохраненные процессы? Какие-то конкретные " за " или "против"?

спасибо.

23 ответов


некоторые преимущества LINQ над sprocs:

  1. безопасность типа: Я думаю, мы все это понимаем.
  2. абстрагирование: Это особенно верно с LINQ-to-Entities. Эта абстракция также позволяет фреймворку добавлять дополнительные улучшения, которыми вы можете легко воспользоваться. PLINQ является примером добавления многопоточной поддержки в LINQ. Изменения кода минимальны для добавления этой поддержки. Это гораздо сложнее сделать этот код доступа к данным, который просто вызывает sprocs.
  3. отладка поддержки: Я могу использовать любой отладчик .NET для отладки запросов. С sprocs вы не можете легко отлаживать SQL, и этот опыт в значительной степени привязан к поставщику базы данных (MS SQL Server предоставляет анализатор запросов, но часто этого недостаточно).
  4. агностик поставщика: LINQ работает с большим количеством баз данных, и количество поддерживаемых баз данных будет только увеличиваться. Хранимые процедуры не всегда переносимы между базами данных из-за различного синтаксиса или поддержки функций (если база данных вообще поддерживает sprocs).
  5. развертывание: другие уже упоминали об этом, но проще развернуть одну сборку, чем развернуть набор sprocs. Это также связано с #4.
  6. легче: вам не нужно изучать T-SQL для доступа к данным, и вам не нужно изучать API доступа к данным (например ADO.NET) необходимо для вызова хранимые процедуры. Это связано с #3 и #4.

некоторые недостатки LINQ vs sprocs:

  1. сетевой трафик: sprocs нужно только сериализовать данные sproc-name и аргумента по проводу, в то время как LINQ отправляет весь запрос. Это может быть очень плохо, если запросы очень сложны. Однако абстракция LINQ позволяет Microsoft улучшить это с течением времени.
  2. менее гибкий: Sprocs может в полной мере использовать преимущества базы данных объекты featureset. LINQ имеет тенденцию быть более общим в своей поддержке. Это распространено в любой абстракции языка (например, C# vs assembler).
  3. перекомпиляции: Если вам нужно внести изменения в способ доступа к данным, вам необходимо перекомпилировать, версию и повторно развернуть сборку. Хранимые процедуры могут иногда разрешить DBA настраивать процедуру доступа к данным без необходимости повторного развертывания чего-либо.

безопасность и управляемость-то, что люди тоже спорят.

  1. безопасность: например, вы можете защитить свои конфиденциальные данные, ограничив доступ к таблицам напрямую и поставив ACLs на sprocs. Однако с LINQ вы все равно можете ограничить прямой доступ к таблицам и вместо этого поместить ACLs в обновляемую таблицу вид для достижения аналогичной цели (при условии, что ваша база данных поддерживает обновляемые представления).
  2. управляемость: использование представлений также дает вам преимущество защиты приложения от изменений схемы (например, нормализация таблицы). Вы можете обновить представление, не требуя изменения кода доступа к данным.

раньше я был большим парнем sproc, но я начинаю склоняться к LINQ как лучшей альтернативе в целом. Если есть некоторые области, где sprocs явно лучше, то я, вероятно, все равно напишу sproc, но доступ к нему с помощью LINQ. :)


Я, как правило, сторонник размещения всего в хранимых процедурах по всем причинам, которые DBAs повторяют в течение многих лет. В случае Linq верно, что с простыми запросами CRUD не будет разницы в производительности.

но имейте в виду несколько вещей при принятии этого решения: используя любые пары ORM вы плотно к вашей модели данных. У DBA нет свободы вносить изменения в модель данных, не заставляя вас изменять скомпилированный код. С хранимыми процедуры, вы можете скрыть эти виды изменений в степени, так как список параметров и результирующий набор(ы), возвращенные из процедуры, представляют ее контракт, и внутренности могут быть изменены вокруг, только до тех пор, пока этот контракт все еще выполняется.

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

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

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


Linq to Sql.

Sql server будет кэшировать планы запросов, поэтому для sprocs нет повышения производительности.

ваши операторы linq, с другой стороны, будут логически частью и протестированы с вашим приложением. Sprocs всегда немного отделены и труднее поддерживать и тестировать.

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


для получения основных данных я бы пошел на Linq без колебаний.

с момента перехода в Linq я нашел следующие преимущества:

  1. отладка моего DAL никогда не было проще.
  2. безопасность времени компиляции при изменении схемы бесценна.
  3. развертывание проще, потому что все скомпилировано в DLL. Больше нет управления сценариями развертывания.
  4. потому что Linq может поддерживать запрос всего, что реализует Интерфейс IQueryable, вы сможете использовать тот же синтаксис для запроса XML, объектов и любого другого источника данных без необходимости изучать новый синтаксис

LINQ раздует кэш процедур

Если приложение использует LINQ to SQL, а запросы включают использование строк, которые могут быть сильно переменными по длине, кэш процедур SQL Server будет раздут с одной версией запроса для каждой возможной длины строки. Например, рассмотрим следующие очень простые запросы, созданные против личности.Таблица AddressTypes в базе данных AdventureWorks2008:

var p = 
    from n in x.AddressTypes 
    where n.Name == "Billing" 
    select n;

var p = 
    from n in x.AddressTypes 
    where n.Name == "Main Office" 
    select n;

если выполняются оба этих запроса, мы увидим две записи в кэше процедур SQL Server: одна связана с NVARCHAR(7), а другая-с NVARCHAR(11). Теперь представьте, если бы были сотни или тысячи различных входных строк, все с разной длиной. Кэш процедур стал бы излишне заполнен всевозможными различными планами для одного и того же запроса.

подробнее здесь: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363290


Я думаю, что аргумент pro LINQ, похоже, исходит от людей, у которых нет истории с разработкой базы данных (в целом).

особенно при использовании продукта, такого как VS DB Pro или Team Suite, многие из приведенных здесь аргументов не применяются, например:

труднее поддерживать и тестировать: VS обеспечивает полную проверку синтаксиса, проверку стиля, проверку ссылок и ограничений и многое другое. Оно также обеспечивает полные возможности и рефакторинг испытания блока инструменты.

LINQ делает истинное модульное тестирование невозможным, поскольку (на мой взгляд) он не проходит кислотный тест.

отладка проще в LINQ: Почему? VS позволяет выполнять полный шаг из управляемого кода и регулярную отладку SPs.

скомпилирован в одну DLL, а не сценарии развертывания: Еще раз, VS приходит на помощь, где он может создавать и развертывать полные базы данных или делать безопасные для данных инкрементные изменения.

Не нужно изучать TSQL с LINQ: Нет, ты не знаешь, но ты ... должны выучить LINQ-где преимущество?

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

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

прежде чем вы все расстроитесь, я думаю, что LINQ имеет свое место и имеет большое будущее. Но для сложных, интенсивных приложений я не думаю, что он готов занять место хранимых процедур. Это был взгляд, который я повторил MVP в TechEd в этом году (они останутся безымянными).

изменить: Сторона хранимой процедуры LINQ to SQL - это то, что мне все еще нужно прочитать больше - в зависимости от того, что я нахожу, я могу изменить свою выше обличительную речь ;)


LINQ является новым и имеет свое место. LINQ не изобретен для замены хранимой процедуры.

здесь я сосредоточусь на некоторых мифах о производительности и минусах, только для "LINQ to SQL", конечно, я могу быть совершенно неправ ;-)

(1)Люди говорят, что LINQ statment может "кэшировать" в SQL server, поэтому он не теряет производительности. Частично верно. "LINQ to SQL" на самом деле является средой выполнения, переводящей синтаксис LINQ в состояние TSQL. Так что с точки зрения производительности,жестко ADO.NET оператор SQL нет разницы, чем LINQ.

(2)приведенный пример, служба поддержки ИП есть счет "переноса" функции. сама эта функция может обновлять таблицы 10 дБ и возвращать некоторые сообщения одним выстрелом. С помощью LINQ вы должны создать набор инструкций и отправить их как один пакет на SQL server. производительность этого переведенного пакета LINQ - >TSQL вряд ли может соответствовать хранимой процедуре. Причина? поскольку можно настроить наименьшую единицу инструкции в хранимой процедуре с помощью встроенного SQL профилировщик и инструмент план выполнения, вы не можете сделать это в LINQ.

дело в том, что при разговоре с одной таблицей БД и небольшим набором данных CRUD LINQ работает так же быстро, как SP. Но для гораздо более сложной логики хранимая процедура более удобна для настройки производительности.

(3)"LINQ to SQL" легко заставляет новичков вводить свиней производительности. Любой старший парень TSQL может сказать вам, когда не использовать курсор (в основном вы не должны использовать курсор в TSQL в большинстве случаев). С LINQ и очаровательным " foreach" цикл с запросом, это так легко для новичка, чтобы написать такой код:

foreach(Customer c in query)
{
  c.Country = "Wonder Land";
}
ctx.SubmitChanges();

вы можете видеть, что этот простой приличный код настолько привлекателен. Но под капотом .NET runtime просто переводит это в пакет обновления. Если есть только 500 строк, это 500 строк пакета TSQL; если есть миллион строк, это хит. Конечно, опытный пользователь не будет использовать этот способ для выполнения этой работы, но дело в том, что так легко упасть таким образом.


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


LINQ определенно имеет свое место в прикладных базах данных и в малых предприятиях.

но на большом предприятии, где центральные базы данных служат центром общих данных для многих приложений, нам нужна абстракция. Нам нужно централизованно управлять безопасностью и показывать истории доступа. Мы должны иметь возможность проводить анализ влияния: если я внесу небольшое изменение в модель данных для удовлетворения новых потребностей бизнеса, какие запросы необходимо изменить и какие приложения необходимо повторно протестировать? Представления и хранимые процедуры дают мне это. Если LINQ может сделать все это и сделать наших программистов более продуктивными, я приветствую это-у кого-нибудь есть опыт использования его в такой среде?


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

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


IMHO, RAD = LINQ,RUP = сохраненные процессы. Я много лет работал в крупной компании из списка Fortune 500, на многих уровнях, включая менеджмент, и, честно говоря, никогда бы не нанял разработчиков RUP для разработки RAD. Они настолько заглушены, что у них очень ограниченные знания о том, что делать на других уровнях процесса. В среде siloed имеет смысл предоставить DBAs контроль над данными через очень конкретные точки входа, потому что другие откровенно не знают лучших способов выполнения данных управление.

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

иногда я думаю, что DBAs предвзято относятся к LINQ, потому что они чувствуют, что это угрожает их безопасности работы. Но такова природа зверя, дамы и господа.


Я думаю, вам нужно пойти с procs для чего-то реального.

A) запись всей вашей логики в linq означает, что ваша база данных менее полезна, потому что только ваше приложение может ее использовать.

B) я не уверен, что объектное моделирование лучше, чем реляционное моделирование.

C) тестирование и разработка хранимой процедуры в SQL намного быстрее, чем цикл редактирования компиляции в любой среде Visual Studio. Вы просто редактируете, F5 и нажимаете select и вы отправляемся на скачки.

D) проще управлять и развертывать хранимые процедуры, чем сборки.. вы просто кладете файл на сервер и нажимаете F5...

E) Linq to sql по-прежнему пишет дерьмовый код, когда вы его не ожидаете.

честно говоря, я думаю, что конечная вещь была бы для MS, чтобы увеличить t-sql, чтобы он мог сделать проекцию соединения имплицитно, как это делает linq. t-sql должен знать, хотите ли вы сделать заказ.lineitems.часть, например.


LINQ не запрещает использование хранимых процедур. Я использовал смешанный режим с LINQ-SQL и LINQ-storedproc. Лично я рад, что мне не придется писать хранимые процедуры....pwet-ту.


также существует проблема возможного отката 2.0. Поверьте мне, это случилось со мной пару раз, поэтому я уверен, что это случилось с другими.

Я также согласен, что абстракция лучше всего. Наряду с тем, что первоначальная цель любого ORM состоит в том, чтобы сделать РСУБД хорошо соответствовать концепциям ОО. Однако, если все работало нормально до LINQ, немного отклоняясь от концепций OO, тогда вверните их. Понятия и реальность не всегда хорошо сочетаются. Там нет места для воинствующие фанатики в нем.


Я предполагаю, что Вы имеете в виду Linq to Sql

для любой команды CRUD легко профилировать производительность хранимой процедуры по сравнению с любой технологией. В этом случае разница между ними будет незначительной. Попробуйте профилировать объект поля 5 (простые типы) более 100 000 запросов select, чтобы узнать, есть ли реальная разница.

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


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

В заключение, выбор между мотоциклом или автомобилем зависит от вашего маршрута (бизнеса), длины (времени) и пассажиров (данных).

надеюсь, это поможет, я могу ошибаться. : D


все эти ответы, склоняющиеся к LINQ, в основном говорят о легкости разработки, которая более или менее связана с низким качеством кодирования или ленью в кодировании. Я только такой.

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

снова TypeSafety, это предупреждение, что "мы осторожны, чтобы избежать неправильной типизации", которое снова плохое качество мы пытаемся улучшить с помощью linq. Даже в этом случае, если что-то в базе данных изменится, например размер столбца String, linq необходимо будет повторно скомпилировать и без этого не будет типизирован .. Я пытался.

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

перестать лениться. Я очень стараюсь. :)


сохраненные Procs vs Code (предыдущее обсуждение)


для простых операций CRUD с одной точкой доступа к данным, я бы сказал, перейти на LINQ, если вы чувствуете себя комфортно с синтаксисом. Для более сложной логики я думаю, что sprocs более эффективны с точки зрения производительности, если Вы хороши в T-SQL и его более продвинутых операциях. У вас также есть помощь от Tuning Advisor, SQL Server Profiler, отладки ваших запросов от SSMS и т. д.


хранимая процедура упрощает тестирование, и вы можете изменить запрос, не касаясь кода приложения. Также с linq получение данных не означает, что это правильные данные. И проверка правильности данных означает запуск приложения, но с хранимой процедурой легко проверить, не касаясь приложения.


результат можно суммировать как

LinqToSql для небольших сайтов и прототипов. Это действительно экономит время на прототипирование.

Sps: Универсальный. Я могу настроить свои запросы и всегда проверять ActualExecutionPlan / EstimatedExecutionPlan.


Create PROCEDURE userInfoProcedure
    -- Add the parameters for the stored procedure here
    @FirstName varchar,
    @LastName varchar
AS
BEGIN

    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT FirstName  , LastName,Age from UserInfo where FirstName=@FirstName
    and LastName=@FirstName
END
GO

http://www.totaldotnet.com/Article/ShowArticle121_StoreProcBasic.aspx


оба LINQ и SQL имеют свои места. У обоих есть свои недостатки и преимущества.

иногда для получения сложных данных вам могут понадобиться хранимые процессы. И иногда вы можете захотеть, чтобы другие люди использовали ваш сохраненный proc в SQL Server Management Studio.

Linq to Entities отлично подходит для быстрого развития CRUD.

конечно, вы можете создать приложение, используя только один или другой. Или ты можешь все перепутать. Все сводится к вашим требованиям. Но SQL хранит procs не уйдет в ближайшее время.