我正在使用WPF,Entity Framework 5,并且正在尝试实现某种Repository模式并以优雅的方式处理连接异常。
我理解在Try / Catch块中包装数据库CRUD操作的概念,以处理数据库无法连接的情况。当然,每个操作都可以抛出多个异常,例如外键约束违规。好的...所以我创建了一个精心设计的Try / Catch块来全面处理所有异常...但这只是一个操作!显然,一个真实世界的应用程序将拥有数十或数百个CRUD操作的代码。当然,为每个单独的CRUD操作复制精细的try / catch块并不是最佳实践。 在应用程序级别最好处理这种事情,在这种情况下,单个CRUD不会因捕获异常而烦恼,然后会出现未处理的异常被捕获到顶部的情况? 理想情况下,我希望我的应用程序具有整体数据库连接状态,如果由于连接相关问题导致任何CRUD操作失败,则将设置为“已断开连接”。
专业应用如何处理这个问题?我错过了什么基本的东西?
谢谢。
答案 0 :(得分:2)
答案是创建一个数据访问层,其中所有数据库函数都通过一个类进行路由。这样,您就可以在一个地方处理所有Exception
。在我的应用程序中,我通过在一个地方处理标准(预期)Exception
来扩展这个想法,然后将数据库查询结果打包到一个帮助程序类中,如果发生了一个,则可以包含Exception
作为结果。不想放弃我的所有代码,这是一个简化的例子:
public GetDataOperationResult<TResult> TryGet<TResult>(Func<TResult> function, int maximumRetryCount, string successText, string undeterminedErrorText)
{
Debug.Assert(function != null, "The function input parameter of the DataOperationManager.TryGet<TResult>() method must not be null.");
for (int index = 0; index < maximumRetryCount; index++)
{
try
{
TResult result = function();
return new GetDataOperationResult<TResult>(result, successText, undeterminedErrorText);
}
catch (Exception exception)
{
if (index == maximumRetryCount - 1) return new GetDataOperationResult<TResult>(exception, successText, undeterminedErrorText);
int sleepCount = GetSleepTime(index, minimumDelay);
Thread.Sleep(sleepCount);
}
}
return new GetDataOperationResult<TResult>(default(TResult), successText, undeterminedErrorText);
}
数据库调用作为Func<TResult>
(与Func<T>
相同)传入,此方法如下所示:
public GetDataOperationResult<User> GetUser(Guid userId)
{
return DataManager.TryGet<User>(() => DataProvider.GetUser(userId), "The user was
loaded successfully", "There was a problem loading the user");
}
虽然我不关心显示GetDataOperationResult
类,但这是标准Exception
处理的地方,以及用户反馈消息生成和/或操作。我相信你可以在没有这个的情况下处理你自己的Exception
。最后要说的是,我的班级中还有TrySet
和异步的get / set方法......它的不是都由一个方法处理。