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

ализуем большинство наших бизнес-правил в базе данных, используя хранимые процедуры.

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

Например, ошибка базы данных, такая как «Невозможно вставить строку с повторяющимся ключом», аналогична бизнес-правилу «вы не можете иметь более одного Foo с одним именем». Но мы «реализовали» его в наиболее здравом смысле: как уникальное ограничение, которое выдает исключение при нарушении правила.

Другие правила, такие как «Вам разрешено только 100 Foos в день», не вызывают ошибок, скажем так, они изящно обрабатываются специальным кодом, таким какreturn empty dataset что код приложения проверяет и передает обратно на уровень пользовательского интерфейса.

И в этом заключается загвоздка. Наш код пользовательского интерфейса выглядит следующим образом (это код веб-сервисов AJAX.NET, но подойдет любая инфраструктура ajax):

WebService.AddFoo("foo", onComplete, onError); // ajax call to web service

function onComplete(newFooId) {
    if(!newFooId) {
        alert('You reached your max number of Foos for the day')
        return
    }
    // update ui as normal here
}

function onError(e) {
    if(e.get_message().indexOf('duplicate key')) {
        alert('A Foo with that name already exists');
        return;
    }
    // REAL error handling code here
}

(В качестве примечания: я замечаю, что это именно то, что делает stackoverflow, когда вы отправляете комментарии слишком быстро: сервер генерируетHTTP 500 ответ и пользовательский интерфейс ловит его.)

Итак, вы видите, что мы обрабатываем нарушения бизнес-правил в двух местах, одно из которых (то есть уникальная ошибка containt) обрабатывается как особый случай кода, который должен обрабатыватьреальный ошибки (не нарушения бизнес-правил), поскольку .NET распространяет исключения вплоть доonError() обработчик.

Это чувствует себя неправильно. Мои варианты, я думаю, следующие:

поймать исключение «нарушение дублированного ключа» на уровне сервера приложений иперерабатывать это все, что ожидает пользовательский интерфейс, поскольку флаг "нарушено бизнес-правило",упредить ошибка (скажем, с"select name from Foo where name = @Name") и вернуть все, что ожидает сервер приложений в качестве флага «нарушено бизнес-правило»,в том же поле, что и 2): использовать уникальное ограничение, встроенное в слой БД, и вслепуюinsert into Fooперехватывает любые исключения и преобразует их во все, что ожидает сервер приложений, поскольку флаг "нарушено бизнес-правило"слепоinsert into Foo (как 3) и пусть это исключение распространяется на пользовательский интерфейс,плюс заставить сервер приложений поднять нарушения бизнес-правил как реальныеExceptions (в отличие от 1). Таким образом, ВСЕ ошибки обрабатываются в слое пользовательского интерфейса.onError() (или аналогичный) код.

Что мне нравится в 2) и 3), так это то, что нарушения бизнес-правил "выбрасываются"где они реализованы: в сохраненной процедуре. Что мне не нравится в 1) и 3) это ядумать они включают в себя глупые проверки, такие как"if error.IndexOf('duplicate key')"так же, как то, что находится в слое пользовательского интерфейса в настоящее время.

редактироватьМне нравится 4), но большинство людей говорят, чтобы использоватьExceptionтолько висключительный обстоятельства.

Итак, как вы, люди, элегантно относитесь к распространяющимся нарушениям бизнес-правил вплоть до пользовательского интерфейса?

Ответы на вопрос(6)

Ваш ответ на вопрос