在 WPF 中数据库不可用时,如何捕获并优雅地处理异常
How can I catch and elegantly handle exception where database is unavailable in WPF
当数据库在带有 EF 的 WPF 中不可用时,我正在尝试捕获异常。我在 C# 中将 MVVM 和 Repo 模式与 IUnityContainer 结合使用。
我的问题是,如果数据库不可用,程序会在视图的代码隐藏中的 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 中向用户提供优雅的响应。所以我的具体问题是当数据库不可用时我在哪里可以捕获异常。
提前致谢。
通常每个 DbContext
周围的 using
将受到 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
我的问题的根本原因是我破坏了封装原则。我想我会是切肉刀,并将经常在列表中引用的 table 放在视图引用的静态 class 中。这就是为什么抛出异常 "outside" ViewModel - 我知道初学者的错误。在我修复了 DbContext 周围的 using 工作正常之后。
谢谢大家的建议
当数据库在带有 EF 的 WPF 中不可用时,我正在尝试捕获异常。我在 C# 中将 MVVM 和 Repo 模式与 IUnityContainer 结合使用。
我的问题是,如果数据库不可用,程序会在视图的代码隐藏中的 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 中向用户提供优雅的响应。所以我的具体问题是当数据库不可用时我在哪里可以捕获异常。
提前致谢。
通常每个 DbContext
周围的 using
将受到 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
我的问题的根本原因是我破坏了封装原则。我想我会是切肉刀,并将经常在列表中引用的 table 放在视图引用的静态 class 中。这就是为什么抛出异常 "outside" ViewModel - 我知道初学者的错误。在我修复了 DbContext 周围的 using 工作正常之后。
谢谢大家的建议