Найкраща практика запиту даних із MS SQL Server у C #?


9

Який найкращий спосіб запиту даних із MS SQL Server у C #?

Я знаю, що не правильно застосовувати SQL-запит у коді.

Це найкращий спосіб створити збережену процедуру і викликати її з C # з параметрами?

using (var conn = new SqlConnection(connStr))
using (var command = new SqlCommand("StoredProc", conn) { CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
   conn.Close();
}

8
"Я знаю, що не правильно застосовувати SQL-запит у коді." - Імо, ось дурниця.
ГрандмайстерB

4
Вам не потрібно дзвонити conn.Close (), якщо ви створили його у використанні блоку. Вся суть блоку використання полягає в тому, щоб імітувати стиль очищення деструктора C ++. Елегантне прибирання з більш цивілізованого віку. Не такий випадковий чи незграбний, як стиль пробування.
Лорд Тидус

2
FYI. Збережені процедури також є "кодом". Вся суть збережених програм полягала в тому, щоб дозволити змішування процедурного коду з набором стилів SQL. Таким чином, у вас буде запит у коді незалежно. Для додатків із надзвичайно великим обсягом іноді краще, щоб логіка виконувалася за межами бази даних, щоб дозволити горизонтальне масштабування шляхом додавання серверів. Якщо ви можете підтримувати єдину БД, але muli-сервер для логіки, то масштабування стає набагато простішим.
Лорд Тидус

@GrandmasterB у нас є значна кількість вбудованого SQL в C # (наш C # LOC зараз майже 2 мільйони) - і через 6 років він повертається, щоб кусати нас, тому що нам зараз потрібно розшукувати цей вбудований SQL (нещодавно ми найняли експерта SQL - значить, ми робимо налаштування продуктивності). Повірте мені: ви ніколи не знаєте, наскільки великим буде ваш додаток і як зміниться ситуація в майбутньому. Зберігайте різні мови в різних файлах - навіть якщо ви просто делегуєте їх для виявлення ресурсів. Ви також можете // SQLCODEце зробити, але для цього потрібно пам'ятати.
Джонатан Дікінсон,

1
@JonathanDickinson, використовуйте збережені програми, якщо хочете. Я багато разів казав, що вони корисні, коли у вас є різні бази коду, що працюють на одній базі даних. Але тільки тому, що вони корисні в деяких обставинах, автоматично не змушуйте весь час використовувати їх «погану практику» . Якщо використання SQL-операторів безпосередньо не викликає проблем, то це не є поганою практикою для цього додатка.
GrandmasterB

Відповіді:


10

Використання збережених процедур є одним із способів і широко застосовується протягом багатьох років.

Більш сучасний спосіб взаємодії з базами даних SQL Server з C # (або будь-якої мови .NET) - це використання Entity Framework. Перевага Entity Framework полягає в тому, що він забезпечує більш високий рівень абстракції.

Цитувати від Microsoft ( https://msdn.microsoft.com/en-us/data/jj590134 ):

Система ADO.NET Entity Framework дозволяє розробникам створювати програми доступу до даних, програмуючи їх на концептуальній моделі програми, а не програмуючи безпосередньо на реляційній схемі зберігання даних. Мета - зменшити кількість коду та обслуговування, необхідне для програм, орієнтованих на дані. Програми Entity Framework надають такі переваги:

  • Програми можуть працювати в контексті концептуальної моделі, орієнтованої на додатки, включаючи типи з успадкуванням, складними членами та відносинами.
  • Програми звільняються від твердо кодованих залежностей певного механізму передачі даних або схеми зберігання.
  • Відображення між концептуальною моделлю та специфічною для зберігання схемою може змінюватися без зміни коду програми.
  • Розробники можуть працювати з послідовною моделлю об'єктної програми, яку можна відобразити на різних схемах зберігання, можливо, реалізованих у різних системах управління базами даних.
  • Кілька концептуальних моделей можуть бути відображені в одній схемі зберігання.
  • Підтримка мовних інтегрованих запитів (LINQ) забезпечує перевірку синтаксису часу компіляції для запитів проти концептуальної моделі.

Використання ORM проти збережених процедур передбачає компроміси, особливо з точки зору безпеки та тих, де існує логіка.

"Класичний" підхід до розробки за допомогою SQL Server полягає в тому, щоб логіка програми знаходилася в збережених процедурах і програмах, що мають лише права безпеки на виконання збережених процедур, а не на оновлення таблиць безпосередньо. Концепція тут полягає в тому, що збережені процедури - це рівень бізнес-логіки для додатків. Незважаючи на те, що теорія є надійною, вона, як правило, не виходить з різних причин, замінюючись реалізацією бізнес-логіки мовою програмування на зразок C # або VB. Хороші програми все ще реалізуються з багаторівневим підходом, включаючи розділення проблем тощо, але, швидше за все, вони дотримуються такої моделі, як MVC.

Одним із недоліків реалізації логіки в ORM, а не в базі даних, є простота налагодження та тестування правил цілісності даних особами, відповідальними за базу даних (DA або DBA). Візьмемо класичний приклад переказу грошей зі свого чеку на ощадний рахунок, важливо, щоб це було зроблено як атомна одиниця роботи, інакше кажучи, промазана транзакцією. Якщо такий вид передачі дозволено здійснювати лише через збережену процедуру, то DA та аудиторам QA відносно легко зберігається збережена процедура.

Якщо, з іншого боку, це робиться за допомогою ORM типу Entity Framework, і в процесі виробництва виявляється, що в рідкісних випадках гроші беруться за перевірку, але не вкладаються в налагодження заощаджень, можуть бути набагато складнішими, особливо якщо потенційно задіяно кілька програм. Це, швидше за все, це кращий випадок, можливо, пов'язаний з особливими апаратними проблемами, які повинні виникати у певній послідовності тощо. Як проводиться тест на це?


Або інша ОРМ. Їх багато, з різними перевагами та недоліками в порівнянні з EF.
svick

8
Перелічення недоліків ORM зробить цю відповідь кориснішою.
День

6

Насправді основне твердження є дискусійним - є компроміси як у випадку між наявністю SQL у коді, так і кодом у базі даних (саме там ви прямуєте із збереженими процедурами).

Підсумком цього є те, що не існує єдиного "найкращого", це не те, що ви можете узагальнити, тому що незалежно від того, яким шляхом ви йдете, ви робите компроміс (ви отримуєте вигоди, але також встановлюєте обмеження).

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

Що ще важливіше - турбуватися про архітектуру та шару вашої програми - якщо відповідний рівень доступу до даних, незалежно від того, чи будуєте ви запити, використовуйте такий ORM, як Entity Framework або NHibernate, або робите щось більш пряме, слід ізолювати більшу частину вашої програми від цього рішення. або використовувати збережені процедури.


Я вільно я прагну працювати над відносно невеликими проектами з невеликими командами (1-3 дев) - використання збережених процедур для мене більше проблем, ніж його варто, оскільки враховуючи, що характер наших програм (і мого набору навичок?) Розгортає нові код, як правило, набагато простіше, ніж оновлення схеми (навіть дозволяючи, що у мене є код, який робить оновлення схеми порівняно простим), і я можу застосовувати ділові правила за допомогою загального коду доступу до даних. Це, очевидно, класичний приклад "Ваша пробіг може варіюватися".


2
+1 для "немає єдиного найкращого", -1 для розгортання коду простіше, ніж розгортання збережених змін облікового запису, +1 для вибору підходу, який має сенс для вашої програми та забезпечує ізоляцію DAL - Так +1.
Джоел Браун

Я кваліфікував біт розгортання з "для мене", тому що це для мене постійно було так (особливо для веб-додатків) - для всього, що це може мати трохи переписати в цій області.
Мерф

+1, що найкраще залежить від програми та ситуації.
GrandmasterB

1
Я думаю, це залежить від умов, в яких ви працюєте. Якщо у вас немає DBA, які не закривали б вас у виробництві, перекидання збереженого протоколу заміни в базу даних може бути страшенно простим. З цього приводу без виробничого контролю викидання нової розмітки, скрипту та навіть нового скомпільованого коду в централізовану програму також може бути дуже просто.
Джоел Браун

@JoelBrown - Точно так - я гадаю, ні, я впевнений, що я зробив цілу грудку припущень. По-перше, моя схема керована версіями (грубо, але ефективно), я не dba, але я досить розумний, щоб знати, що чиясь схема повинна бути послідовною. Я працюю в основному над веб-додатками, і ви не можете дістатися до баз даних, за винятком відвідування сервера, тоді як я (просто) скоротив розгортання програм на (більш-менш) одним клацанням кнопки ... інтегруючи оновлення схеми в зазначене розгортання є в списку, але я завжди вважав, що оновлення схеми є більш напруженими, ніж оновлення коду (простота відкату?)
Мерф

4

Поки ви параметризували свої входи, будь-який підхід є дійсним. Значна частина запитів у аргументах коду виникла з старих поганих часів, коли багато бібліотек змушували вас додавати ваші висловлювання разом, і саме звідси виходили sql-ін'єкційні атаки.


1
Чи достатньо параметризації? Вам також не потрібно санітувати?
StuperUser

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

0

Найкраща практика насправді тут перекрита - є багато хороших способів це зробити, і той, який ви вибрали, дійсно повинен залежати від того, що саме є вашим додатком і що вам потрібно зробити. Однак, є дві речі, які ви можете зробити дійсно неправильно:

  • Як вказує @Bill, ви завжди повинні параметризувати запити. Створення рядків - це простий вектор для ін'єкцій SQL, а також усілякі труднощі для відстеження помилок. Набагато розумніші люди придумали, як настроїти та врятувати sql, тому вам не потрібно розбиратись самі.

  • Закрийте свої зв’язки. Найкращий спосіб - обернути все, використовуючи заяву, але спробуйте / catch / нарешті, це теж круто, якщо це пливе ваш човен. Але завжди переконайтеся, що ви використовуєте таке з'єднання, як дешевий автомобіль - керуйте ним важко і швидко і швидко позбавляйтеся від нього.

Інша практика, за яку я наполегливо стверджую, полягає в тому, що ви повинні переконатися, що ви сконцентрували код доступу до даних якомога менше місць. Ми не дозволяємо переднім веб-програмам прямо посилатися на System.Data.SqlClient, щоб допомогти виконувати цей застереження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.