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





эээ ... может быть, я упускаю что-то очевидное ... но не лучше ли было бы потратить ваше время на исправить ошибку вместо анализа исключения?
@Kay: LOL! Да, это все еще ошибка. Пользователи никогда не должны видеть исключения базы данных, и если вы обнаружите, что анализируете исключения базы данных, чтобы представить их пользователю, то совершенно очевидно, что вы упустили некоторые правила проверки ввода. Вместо этого исправьте отсутствующую проверку.
@Steven, как узнать, какую бизнес-логику это конкретное приложение закодировало в ограничения базы данных? ... И цель джентльмена - ПРЕДОТВРАТИТЬ, что пользователь увидит исключение необработанной базы данных ...
@Steven, нет это не "баг" (ошибка). Если у вас есть имя varchar (20) UNIQUE NOT NULL, то пользователь может попытаться ввести «Джеймс» после того, как он уже введен. Даже если система проверяет сначала, все еще возможно нарушить ограничение с помощью условий гонки.
@ [Чарльз Бретана]: потому что он только что сказал мне в комментарии. Он не пытается помешать пользователю увидеть исключение db, он пытается проанализировать исключение db, чтобы представить информацию более подробно. Вместо проверки нарушения в первую очередь при проверке.
@ [Артур Томас]: да, это ошибка, в частности, отсутствие проверки. И ваш аргумент о состоянии гонки - отвлекающий маневр: вероятность возникновения состояния гонки для вашего примера в нормальной системе исчезающе мала.
Итак, когда это произойдет, хотя и маловероятно, он должен выдать большую неприятную ошибку вместо анализа некоторого исключения db? Я бы предпочел написать еще несколько строк кода, чтобы быть уверенным. Также я могу позволить базе данных сказать мне, что это был обман, вместо того, чтобы проверять вручную. Я просто не думаю, что есть абсолютный способ
@ [Артур Томас]: сколько времени вы тратите на маловероятные исключения db? вы пишете код синтаксического анализа исключений для исключений взаимоблокировки? для исключений при потере соединения? за каждое возможное нарушение ограничений? Похоже, мы делаем много дополнительной работы, чтобы избежать очевидной проверки. ;-)
@Steven, Вы, очевидно, говорите на другом диалекте английского языка, чем все мы .... "разбор исключения для представления информации ...." НЕ позволяет пользователю [напрямую] увидеть исключение ....
@Steven, В ТАКОМ комментарии он специально сказал, что это не проблема проверки ввода данных ...
@ Чарльз: LOL! прямо да, но он делает это вместо подразумеваемой проверки.
@Charles: «он специально сказал, что это не проблема проверки ввода данных»; Я знаю. Он ошибается, это явно проблема проверки ввода данных. ;-) Почему «ключ продукта должен быть уникальным» НЕ является проблемой проверки? Это бизнес-правило в контексте ввода данных, которое не проверяется заранее.
@ [Чарльз Бретана]: подумайте об этом так - проверяете ли вы ввод данных в обязательное поле или ждете, пока база данных не выдаст исключение «поле не может быть нулевым»? Эта ситуация ничем не отличается.
@Steven, Он сказал, что это был пример .... не конкретная проблема ... Он сказал "... исключение LIKE: нарушение ограничения UNIQUE KEY ...". Я понял, что его вопрос касается ограничений в целом, а не конкретных ограничений ...
@ [Чарльз Бретана]: и ваш ответ хорош, но он решает не ту задачу. ;-)
@Steven, я согласен с вашей основной точкой зрения (что, когда это возможно, всегда лучше проверять ввод пользователя в пользовательском интерфейсе, чем позволять ему возвращаться в БД), но не согласен с тем, что этот вопрос пользователя может быть известен абсолютно (просто потому, что это ограничение Unuiqe), чтобы быть в этой категории. Я имею в виду (не)
почти каждая система (включая SO) демонстрирует очевидный пример одного случая, когда пользовательский ввод в произвольной форме должен быть уникальным и, тем не менее, не может (разумно) быть проверен без столкновения с ограничением базы данных ... выбор идентификатора пользователя
@ [Charles Bretana]: он сказал: «В таблице может быть более одного уникального ограничения, и нам нужно знать, какое из них будет предоставлять пользователю более подробную информацию», что четко указывает на категорию ограничения. Кроме того, если база данных может проверить ограничение, то сможете и вы!
@Joel, конечно, все возможно, но это не делает его умным ... например, проверка идентификатора входа, указанного новым пользователем, еще не была выбрана другим пользователем МОЖЕТ быть выполнена при проверке пользовательского интерфейса, но это будет быть наименее предпочтительным подходом. Ваш «один размер подходит всем» - неправильный размер.
@ [Чарльз Бретана]: кто такой Джоэл? Я не вижу здесь ни одного Джоэла ... ;-)
@Steven, извините !, правильная ветка, неправильный UserId [усмехается] и, возможно, хорошая заметка, на которой вежливо закончим нашу дискуссию! Как обычно, когда вдумчивые люди не согласны, мы, кажется, сузили наши точки несогласия до того, что вряд ли стоит затраченных усилий!
@ [Чарльз Бретана]: LOL! На самом деле мы, вероятно, в целом не расходимся во мнениях относительно правильного подхода. Я предполагаю, что вы действительно выполняете хотя бы некоторую проверку в пользовательском интерфейсе, и можете быть уверены, что я также фиксирую нарушения ограничений базы данных. Счастливого Нового года!
Вам нужно будет либо:
Если у вас есть это как исключение, анализ объекта - ваш лучший вариант. Я бы не стал слишком торопиться с тем, чтобы отвергать это как реализацию - регулярные выражения с группой не должно быть слишком сложно улучшить для вашей ситуации.
Вы также можете получить аналогичное решение (синтаксический анализ) в своей сохраненной процедуре. Кроме того, отправляя код синтаксического анализа на сервер базы данных, вы заставляете свои базы данных иметь возможность разрешать точные детали без синтаксического анализа (это может быть тривиально для базы данных A, но исключительно сложно для баз данных B и C).
Звучит как проблема с плохим дизайном. РСУБД должен обеспечивает эти действия, но приложение также должно знать об этих ограничениях и строиться вокруг них. Довольно жестоко ожидать, что ваша RBDMS будет обрабатывать логические исключения, которые ваше приложение должно улавливать или предотвращать с самого начала. Механизмы базы данных предназначены для операций с данными, а не для создания исключений в приложении.
unique - это ограничение, о котором вы не знаете, пока не нажмете db. Вы можете сначала сделать чек, но кто-то может вставить его после чека.
Конечно, но опять же, этого не должно происходить. Если у вас есть проблема с уникальностью, о которой нужно беспокоиться, на уровне приложения должен быть простой кеш для таких вещей. Вы не должны пытаться анализировать сообщения об исключениях базы данных, точка.
Не анализируйте текст исключения. (вторя Эндрю здесь ...)
Если вы ожидаете ряда возможных ошибок при вставке / обновлении данных, вам следует уловить их на своем уровне C#. Расширьте ApplicationException, чтобы создать собственные исключения для обработки определенных ограничений, подобных этим.
Но это предполагает, что ваша модель данных расположена так, что вы можете делать эти определения, не используя базу данных, чтобы сообщить вам, что оператор может быть успешно выполнен. Если ваш дизайн данных не позволяет вам узнать, можете ли вы нарушить ограничения, не запустив его через механизм db, значит, в вашем дизайне данных есть изъян.
В данном случае это не ошибка. Пользователь ввел данные, которые нарушают ограничение базы данных. Мне нужно предоставить им правильную информацию, чтобы они могли исправить введенные данные и повторить попытку. Это скорее проблема проверки, а не ошибка.