Как я могу поймать и элегантно обработать исключение, когда база данных недоступна в WPF
Я пытаюсь поймать исключение, когда база данных недоступна в WPF с EF. Я использую MVVM и шаблон Repo с IUnityContainer в C#.
Моя проблема заключается в том, что, если база данных недоступна, программа аварийно завершает работу оператора InitializeComponent() в коде за представлением. Я попытался выполнить поиск по выявлению исключений и обработке ошибок и т. Д., И большинство предложений сосредоточены вокруг логики Try Catch, что и следовало ожидать. Я попытался обернуть оператор в блок try-catch, как показано ниже, но он все равно вылетает в том же месте на InitalizeComponent.
Public MyListView() {
try {
IntializeComponent();
} catch (Exception) {
throw;
}
}
Я также пытался добавить блоки Try-Catch в различные другие точки моего кода, например, где инициализирована БД:
Database.SetInitializer(new DataInitialiser());
Где зарегистрирован контейнер Unity:
_container.RegisterType<IRepo<MyList>, MyListRepo>(new TransientLifetimeManager());
и куда загружаются данные:
MyLists = new ObservableCollection<MyList>(await _repo.GetAllAsync());
Я хотел бы сохранить шаблон MVVM, поэтому перехватывайте исключение и предоставляйте элегантный ответ пользователю из ViewModel. Поэтому мой конкретный вопрос: где я могу поймать исключение, когда база данных недоступна?
Заранее спасибо.
2 ответа
Типично using
вокруг каждого DbContext
будет защищен try
/ catch
блок.
Если вы хотите что-то более централизованное, вы можете сделать что-то вроде этого:
public static class EfHelper
{
public static void SafeExecute<T>(Action<T> action) where T : DbContext, new()
{
try
{
using (var context = new T())
{
action.Invoke(context);
}
}
catch (Exception ex)
{
// Put your standard error handling here.
Debug.WriteLine("There was an error");
}
}
}
Использование:
void Main()
{
EfHelper.SafeExecute<TestContext>(context =>
{
context.DoSomething();
});
}
Возможно, вы захотите немного расширить это, чтобы позволить вызывающей стороне узнать, была ли операция успешной или неудачной. Вы можете сделать это, вернув bool
или распространение исключения, если установлен другой флаг и т. д.
Если у вас установлен LINQPad, вы можете увидеть простую демонстрацию здесь: http://share.linqpad.net/4x2g36.linq
Основной причиной моей проблемы было то, что я нарушил принцип инкапсуляции. Я думал, что я был бы умным и поместил бы таблицу, на которую часто ссылаются в списке, в статический класс, на который ссылается представление. Вот почему исключение было выброшено "за пределы" ViewModel - я знаю ошибку новичка. После того, как я установил, что использование вокруг DbContext работало отлично.
Спасибо за все советы