Я работаю над приложением базы данных, написанным на C #, с сервером SQL в качестве бэкэнда. А для целостности данных я стараюсь максимально усилить на уровне базы данных - отношения, проверки ограничений, триггеры.
Из-за них, если данные не согласованы, может произойти сбой сохранения / обновления / вставки, и приложение выдаст SqlException.
Я выполняю различные проверки как в пользовательском интерфейсе (чтобы предоставить пользователю значимую информацию, если введенные данные неверны), так и в BL, который сообщает об ошибках обратно в пользовательский интерфейс, который представляет их пользователю.
Однако есть вещи, которые действительно нельзя проверить в приложении, и которые обрабатываются БД: я имею в виду ошибки при удалении, когда нет каскадного удаления, и пользователь пытается удалить объект из основной таблицы и т. Д.
например. Таблица сотрудников действует как мастер в отношениях: менеджер сотрудника, менеджер отдела, кассир, руководитель группы, члены команды и т. Д. И т. Д. Если я добавлю нового сотрудника, который не связан ни с какими отношениями, я могу удалить его, но пользователь попытается удалить тот, который является основным в таком отношении, удаление завершается неудачно (как и должно быть) из-за правил RI, применяемых на уровне БД, и это нормально.
Я пишу код удаления в попытке ... поймать и обработать исключение, сообщая пользователю, что он не может удалить этого сотрудника. Но я хочу дать пользователю более значимую информацию - причина, по которой запись не может быть удалена. Может быть, это была просто запись сотрудника, которая была добавлена в команду тестирования. Но пользователь забыл, где добавил, и если бы я мог сказать «Невозможно удалить сотрудника, потому что он является частью команды T1», пользователь будет знать, что сначала нужно перейти в Team T1, удалить пользователя, а затем попытаться удалить его снова. Это простой пример, поскольку, как я уже сказал, сотрудник может быть вовлечен во многие отношения - в моем приложении у меня есть как минимум 20.
Решение состоит в том, чтобы отобразить Сообщение, сообщаемое SqlException, но это совсем не элегантно. Во-первых, это сообщение очень техническое - оно говорит о FK, PK, Trigger, которые не имеют смысла для пользователей и будут их пугать. Во-вторых, мое приложение использует многоязычный интерфейс, и все меню и сообщения отображаются на выбранном пользователем языке (выбирается либо во время входа в систему, либо в профиле пользователя). И сообщение из SqlException является английским (если я использую английскую версию) или худшими, менее распространенными языками, такими как немецкий или голландский, если случается, что сервер SQL находится на этом языке.
Существует ли какой-либо распространенный или рекомендуемый подход для извлечения значимой информации из исключения sql, чтобы иметь возможность представить пользователю значимое сообщение (например, какое отношение или дочерняя таблица вызвали сбой, или какой триггер и т. Д.). но что-то, что я могу протестировать в программе независимым от языка способом и затем отформатировать мою собственную ошибку msg удобным для пользователя способом?
Как вы справляетесь с этой ситуацией?
Спасибо за все ответы
(PS: простите за длинный пост)