Обработка исключений базы данных в .NET

Когда мы можем поймать исключение, например: Violation of UNIQUE KEY constraint 'IX_Product'. Cannot insert duplicate key in object 'Product'. (2627).
Проблема в том, как расшифровать индексное имя IX_Product как член (т.е. я не хочу выделять сообщение). В таблице может быть несколько уникальных ограничений, и нам нужно знать, какое из них будет предоставлять пользователю более подробную информацию. Было бы предпочтительнее перехватывать его как DbException, чтобы оно не зависело от SQL Server. Есть ли способ получить затронутый индекс из исключения без анализа строки?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
2 640
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

Kay 29.12.2008 19:24

@Kay: LOL! Да, это все еще ошибка. Пользователи никогда не должны видеть исключения базы данных, и если вы обнаружите, что анализируете исключения базы данных, чтобы представить их пользователю, то совершенно очевидно, что вы упустили некоторые правила проверки ввода. Вместо этого исправьте отсутствующую проверку.

Steven A. Lowe 29.12.2008 19:50

@Steven, как узнать, какую бизнес-логику это конкретное приложение закодировало в ограничения базы данных? ... И цель джентльмена - ПРЕДОТВРАТИТЬ, что пользователь увидит исключение необработанной базы данных ...

Charles Bretana 29.12.2008 19:54

@Steven, нет это не "баг" (ошибка). Если у вас есть имя varchar (20) UNIQUE NOT NULL, то пользователь может попытаться ввести «Джеймс» после того, как он уже введен. Даже если система проверяет сначала, все еще возможно нарушить ограничение с помощью условий гонки.

Arthur Thomas 29.12.2008 20:40

@ [Чарльз Бретана]: потому что он только что сказал мне в комментарии. Он не пытается помешать пользователю увидеть исключение db, он пытается проанализировать исключение db, чтобы представить информацию более подробно. Вместо проверки нарушения в первую очередь при проверке.

Steven A. Lowe 29.12.2008 22:49

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

Steven A. Lowe 29.12.2008 22:50

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

Arthur Thomas 29.12.2008 23:25

@ [Артур Томас]: сколько времени вы тратите на маловероятные исключения db? вы пишете код синтаксического анализа исключений для исключений взаимоблокировки? для исключений при потере соединения? за каждое возможное нарушение ограничений? Похоже, мы делаем много дополнительной работы, чтобы избежать очевидной проверки. ;-)

Steven A. Lowe 30.12.2008 00:04

@Steven, Вы, очевидно, говорите на другом диалекте английского языка, чем все мы .... "разбор исключения для представления информации ...." НЕ позволяет пользователю [напрямую] увидеть исключение ....

Charles Bretana 30.12.2008 03:56

@Steven, В ТАКОМ комментарии он специально сказал, что это не проблема проверки ввода данных ...

Charles Bretana 30.12.2008 03:57

@ Чарльз: LOL! прямо да, но он делает это вместо подразумеваемой проверки.

Steven A. Lowe 30.12.2008 05:05

@Charles: «он специально сказал, что это не проблема проверки ввода данных»; Я знаю. Он ошибается, это явно проблема проверки ввода данных. ;-) Почему «ключ продукта должен быть уникальным» НЕ является проблемой проверки? Это бизнес-правило в контексте ввода данных, которое не проверяется заранее.

Steven A. Lowe 30.12.2008 05:08

@ [Чарльз Бретана]: подумайте об этом так - проверяете ли вы ввод данных в обязательное поле или ждете, пока база данных не выдаст исключение «поле не может быть нулевым»? Эта ситуация ничем не отличается.

Steven A. Lowe 30.12.2008 05:38

@Steven, Он сказал, что это был пример .... не конкретная проблема ... Он сказал "... исключение LIKE: нарушение ограничения UNIQUE KEY ...". Я понял, что его вопрос касается ограничений в целом, а не конкретных ограничений ...

Charles Bretana 30.12.2008 06:18

@ [Чарльз Бретана]: и ваш ответ хорош, но он решает не ту задачу. ;-)

Steven A. Lowe 30.12.2008 06:23

@Steven, я согласен с вашей основной точкой зрения (что, когда это возможно, всегда лучше проверять ввод пользователя в пользовательском интерфейсе, чем позволять ему возвращаться в БД), но не согласен с тем, что этот вопрос пользователя может быть известен абсолютно (просто потому, что это ограничение Unuiqe), чтобы быть в этой категории. Я имею в виду (не)

Charles Bretana 30.12.2008 17:28

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

Charles Bretana 30.12.2008 17:28

@ [Charles Bretana]: он сказал: «В таблице может быть более одного уникального ограничения, и нам нужно знать, какое из них будет предоставлять пользователю более подробную информацию», что четко указывает на категорию ограничения. Кроме того, если база данных может проверить ограничение, то сможете и вы!

Steven A. Lowe 30.12.2008 17:41

@Joel, конечно, все возможно, но это не делает его умным ... например, проверка идентификатора входа, указанного новым пользователем, еще не была выбрана другим пользователем МОЖЕТ быть выполнена при проверке пользовательского интерфейса, но это будет быть наименее предпочтительным подходом. Ваш «один размер подходит всем» - неправильный размер.

Charles Bretana 31.12.2008 00:17

@ [Чарльз Бретана]: кто такой Джоэл? Я не вижу здесь ни одного Джоэла ... ;-)

Steven A. Lowe 31.12.2008 02:04

@Steven, извините !, правильная ветка, неправильный UserId [усмехается] и, возможно, хорошая заметка, на которой вежливо закончим нашу дискуссию! Как обычно, когда вдумчивые люди не согласны, мы, кажется, сузили наши точки несогласия до того, что вряд ли стоит затраченных усилий!

Charles Bretana 31.12.2008 04:09

@ [Чарльз Бретана]: LOL! На самом деле мы, вероятно, в целом не расходимся во мнениях относительно правильного подхода. Я предполагаю, что вы действительно выполняете хотя бы некоторую проверку в пользовательском интерфейсе, и можете быть уверены, что я также фиксирую нарушения ограничений базы данных. Счастливого Нового года!

Steven A. Lowe 31.12.2008 17:06
Ответ принят как подходящий

Вам нужно будет либо:

  1. закодируйте свой клиентский компонент на распознавать имена ограничений, которые каждый оператор вставки / обновления может выбрасывать исключения для,
  2. переименуйте все ваши ограничения, чтобы их можно было «расшифровать» так, как вы хотите использовать их в клиентском коде, или ...
  3. проверьте все ограничения в сохраненной процедуре перед попыткой вставки / обновления и бросьте (поднимите) свое собственное исключение в процедуре, если проверка не удалась, ПЕРЕД попыткой обновления вставки и позволив ограничению создать исключение ...

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

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

Звучит как проблема с плохим дизайном. РСУБД должен обеспечивает эти действия, но приложение также должно знать об этих ограничениях и строиться вокруг них. Довольно жестоко ожидать, что ваша RBDMS будет обрабатывать логические исключения, которые ваше приложение должно улавливать или предотвращать с самого начала. Механизмы базы данных предназначены для операций с данными, а не для создания исключений в приложении.

unique - это ограничение, о котором вы не знаете, пока не нажмете db. Вы можете сначала сделать чек, но кто-то может вставить его после чека.

Arthur Thomas 29.12.2008 20:41

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

andrewbadera 30.12.2008 00:28

Не анализируйте текст исключения. (вторя Эндрю здесь ...)

Если вы ожидаете ряда возможных ошибок при вставке / обновлении данных, вам следует уловить их на своем уровне C#. Расширьте ApplicationException, чтобы создать собственные исключения для обработки определенных ограничений, подобных этим.

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

Другие вопросы по теме