2009-04-07 2 views

ответ

5

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

Если все, что вы делаете, это просто инструкции INSERT, UPDATE и DELETE LINQ - это путь (по моему мнению), и вся оптимизация выполняется для вас, для более сложной работы я бы сказал, процедуры.

+2

На самом деле, поскольку выполнение запроса отложено, пока вы не делаете что-то вроде ToArray в середине, он будет обрабатывать соединения правильно и позволить БД делать то, что он делает лучше всего. Если вы говорите о ширине строки, вы всегда можете использовать анонимные объекты, и она сделает правильный выбор. –

+0

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

+0

erm ... LINQ предназначен для запросов, а не для вставок, удалений или чего-либо еще. – BlackTigerX

2

Я предполагаю, что вы имеете в виду LINQ to SQL как LINQ и хранимые процедуры - это две разные вещи.

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

4

С моей точки зрения, основное значение хранимых процедур было устранено с помощью LINQToSQL. В течение долгого времени ключевым значением использования хранимых процедур было инкапсулирование SQL в форму, в которой вы, естественно, использовали параметризованные запросы. Это обеспечило разработчику уровень безопасности для SQL-инъекций. Поскольку запросы LINQToSQL по умолчанию параметризуются, я обнаружил, что мое использование хранимых процедур значительно сократилось.

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

Обратите внимание, что вы все еще можете использовать хранимые процедуры с LINQToSQL. Я просто не очень ценю этого. На самом деле, я не могу представить ни одной хранимой процедуры, которую я написал с момента перехода на LINQToSQL, хотя я написал несколько табличных функций для выполнения определенных поисков. Они попадают в мой DataContext и отображаются как методы, которые я могу вызвать для получения соответствующих объектов из БД с помощью этой функции.

+0

LINQ to SQL по-прежнему гораздо менее безопасен, потому что вы должны предоставить доступ на уровне таблицы, который вам не нужно делать с правильно написанными процедурами. Вы можете защитить ОК от снаружи, но вы позволяете потенциальным мошенникам в вашей системе инсайдерами. – HLGEM

+0

Разница заключалась бы в том, что я контролирую доступ на уровне приложения через роли, а не на уровне базы данных. Никто не имеет доступа, используя свои собственные учетные данные. Весь доступ фильтруется через уровень разрешений поверх контекста данных LINQToSQL. – tvanfosson

10

Поскольку никто не добавил CON - я предложу один здесь ...

Хранимые Procs предлагают вам возможность запретить выбор/вставки/удаления/обновления ваших базовых таблиц и представлений, так что вы могли бы потенциально улучшая безопасность, используя хранимые процедуры, как вы могли бы использовать Linq to SQL. Предоставляя разрешения на выполнение только для ваших процессов, у вас есть меньшая площадь для управления безопасностью.

Конечно, вы все равно можете использовать Linq для SQL и хранить вместе procs - возможно, это был бы лучший вариант.

+0

+1 Ударь меня, вот что я набирал ... –

+0

И то, что я сказал ранее, но мое было многословным. :) –

+0

Это может быть больше PRO для хранимых процедур, чем действительно CON для LINQ. это еще один уровень для контроля авторизации ресурсов. Но это делается и на других слоях, например. приложение, и мы не говорим, что это * недостаток * хранимых процессов - это то, что они не имеют доступа, например. API безопасности ASP.NET, хотя C#. –

1

Я говорил об этом с кем-то здесь на днях, так как мы используем хранимые процедуры для всего доступа к базе данных в настоящее время. Мы обсуждали LINQ в целом и реализацию LINQ to SQL, IQueryable и т. Д. Она быстро поняла, что использование LINQ с sprocs будет в лучшем случае избыточным и сложным в худшем случае.

Преимущества LINQ to SQL в том, что код живет в одном месте, а то, что происходит в БД, очень ясно. Кроме того, время разработки может быть меньше, в основном в зависимости от процесса, так как есть один меньше рабочего продукта.

Преимущества Sprocs, как я вижу, также двоякие. Хранимые процедуры позволяют значительно улучшить контроль доступа для администратора базы данных, поскольку они могут проверять sproc перед развертыванием и разрешать приложению использовать доступ только для выполнения этого sproc, а не для чтения/записи для всех необходимых таблиц. Это позволяет значительно лучше анализировать проблемы конкуренции и производительности баз данных. Другое преимущество, которое я вижу, заключается в том, что хотя LINQ to SQL генерирует правильный запрос, в случае сложных запросов бывают случаи, когда вы попадаете в случай, который приводит к плохой оптимизации на стороне БД. В этих случаях вы либо переписываете запрос, либо предоставляете подсказки оптимизатору, оба являются сложными/невозможными/метафорами с LINQ.

Может быть, это DBA во мне (не DBA, но были), но я очень нервничаю при работе с большой высокой нагрузкой DB и не знаю точно все возможные утверждения, которые будут выполняться системой , Таким образом, я сам придерживаюсь sprocs.

0

Я широко использую LINQ-to-SQL в своих проектах и ​​нашел, что он работает, а также SP почти во всех случаях.

Есть некоторые случаи, в которых вы теряете производительность/способность с помощью LINQ к SQL, без сомнения:

  • Поскольку запросы завернутые в коде с помощью LINQ, вы не можете использовать Встроенный в SQL оптимизатор запросов/оптимизатор индекса (как легко). Такие вещи, как отслеживание планов выполнения, также делают дополнительный шаг (получение генерируемого sql). Довольно тривиальный, я думаю.

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

3

Есть несколько вещей, которые я хотел бы добавить к обсуждению:

  • Linq меньше шансов попасть кэшированный план выполнения в SQL Server, чем в хранимой процедуре. Хотя компиляция базовых операторов выбора является легкой, в более сложных запросах компиляция может быть довольно дорогостоящей. (При множестве факторов нужно сделать это утверждение истинным/ложным для вашей ситуации, но это, вероятно, для другого поста).

  • Если у вас есть перекодированные данные, то перекомпиляция может фактически быть преимуществом для предотвращения использования нечетных индексов SQL. Think select * FROM Person where LastName = @Letter Первый проход, где @Letter='Z' (скажем, 0,25% от общего числа людей) против @Letter='S' (6,00% от общего числа людей) может привести к совершенно разным планам исполнения.

  • Linq эффективно повторно вводит специальный htl в наш код. Предоставил его через слой абстракции и на новом языке, но больше не я вызываю exec GetOrders @[email protected] @DayRange=7, вместо этого я пишу свое имя таблицы, где предложение и порядок.

  • Отслеживание неактивных SQL-запросов обратно к коду, сгенерировавшемуся инструкциями, более сложным, чем с SP. В среде с большими объемами SQL-профилер часто запускается на регулярной основе, чтобы найти не-исполняемые запросы (высокий процессор, чтение или длительность). Поскольку Linq абстрагирует текст, который он создает, становится сложнее отслеживать sql обратно в определенное место в коде, особенно в больших приложениях.

  • В качестве дополнительного примечания, при необходимости Linq может вызывать определенную хранимую процедуру, а не генерировать собственный SQL. См. Это Scott Gu article.

+0

Что касается «Linq с меньшей вероятностью попадет в план выполнения кэширования»: я обнаружил, что запросы, сгенерированные LINQ, с большей вероятностью будут генерировать несколько планов на запрос - и, хотя для этого требуется немного времени для «кэширования» нового сервера, создаваемые планы более специализированы, тем самым часто повышая производительность. – NTDLS

+0

@NTDLS - Я согласен по большей части. Генерация запросов Linq развилась, так как я написал это, чтобы лучше совместить с вашей перспективой. Более (+ более конкретные) планы * могут * повысить производительность - они * могут также * ухудшить производительность. В достаточно большой/переменной системе слишком много планов может привести к очистке кеша, чтобы освободить ресурсы, что приведет к меньшему количеству кэшированных запросов. Кроме того, неявное в моем заявлении было то, что в SQL 2008 я могу привязать «правильный» план выполнения SP и избежать ошибок, искажаемых данными и параметром sniffing. Наверное, поэтому я поставил отказ в этом вопросе. – EBarr

1

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

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

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

Если он не работает хорошо, я могу работать над запросом, пока это не произойдет.

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

Даже теория доступа к перекрестным базам данных «если я напишу ее в linq, я могу использовать любую базу данных, которую я хочу», не интересует меня, особенно если я пишу, скажу SQL Azure, где я точно знаю, какая база данных это будет.

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

0

Что относительно модульности?

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

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

Опять же, мне нравятся LINQ и функции, которые приходят с этим ... но я не совсем продаю LINQ-TO-SQL.