在WPF中数据库不可用的情况下,如何捕获并优雅地处理异常

时间:2018-06-21 10:26:35

标签: wpf entity-framework exception mvvm initializecomponent

当数据库在EF的WPF中不可用时,我正在尝试捕获异常。我在C#中将MVVM和回购模式与IUnityContainer一起使用。

我的问题是,如果数据库不可用,则该程序将在View背后的代码中的InitializeComponent()语句上崩溃。我尝试搜索捕获异常和错误处理等,并且大多数建议都围绕“尝试捕获”逻辑,这是可以预期的。我试图将语句包装在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 个答案:

答案 0 :(得分:0)

Typically the using around each DbContext would be protected by a try / catch block.

If you want something a little more centralized, you could do something like this:

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");
        }
    }
}

Usage:

void Main()
{
    EfHelper.SafeExecute<TestContext>(context =>
    {
        context.DoSomething();
    });
}

You would probably want to expand this a bit to allow the caller to know if the operation succeeded or failed. You could do that by returning a bool, or propagating the exception if another flag is set, etc.

If you have LINQPad installed, you can see a simple demo here: http://share.linqpad.net/4x2g36.linq

答案 1 :(得分:0)

我的问题的根本原因是我破坏了封装主体。我以为我会被砍刀,并把一个表,该表经常在视图引用的静态类的列表中被引用。这就是为什么在ViewModel外部抛出异常的原因-我知道是初学者的错误。在我修复DbContext周围的使用效果很好之后。

感谢所有建议