如何重构冗余的try catch代码
本文关键字:try catch 代码 冗余 何重构 重构 | 更新日期: 2023-09-27 18:14:14
我正在尝试确定重构这段代码的最佳方法。如你所见,尝试…抓住. .抓住. .赶上……代码行是相同的。这两个方法之间的唯一区别是一个是异步的,而另一个不是。
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
var entityValidationErrors = ex.EntityValidationErrors
.SelectMany(e => e.ValidationErrors)
.Select(x => string.Format("{0} - {1}", x.PropertyName, x.ErrorMessage));
var fullErrorMessage = string.Join(Environment.NewLine, entityValidationErrors);
var exceptionMessage = string.Concat(ex.Message, " Entity validation errors: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
catch (DbUpdateConcurrencyException ex)
{
Debug.WriteLine(ex.Message);
throw;
}
catch (DbUpdateException ex)
{
var sqlException = ex.GetBaseException() as SqlException;
if (sqlException == null || sqlException.Errors.Count <= 0)
throw;
var errors = new List<string>();
for (var i = 0; i < sqlException.Errors.Count; i++)
{
errors.Add(string.Format("{0} - {1}", sqlException.Errors[i].Number, sqlException.Errors[i].Message));
}
throw new DbUpdateException(string.Join(Environment.NewLine, errors));
}
}
public override async Task<int> SaveChangesAsync()
{
try
{
return await base.SaveChangesAsync();
}
catch (DbEntityValidationException ex)
{
var entityValidationErrors = ex.EntityValidationErrors
.SelectMany(e => e.ValidationErrors)
.Select(x => string.Format("{0} - {1}", x.PropertyName, x.ErrorMessage));
var fullErrorMessage = string.Join(Environment.NewLine, entityValidationErrors);
var exceptionMessage = string.Concat(ex.Message, " Entity validation errors: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
catch (DbUpdateConcurrencyException ex)
{
Debug.WriteLine(ex.Message);
throw;
}
catch (DbUpdateException ex)
{
var sqlException = ex.GetBaseException() as SqlException;
if (sqlException == null || sqlException.Errors.Count <= 0)
throw;
var errors = new List<string>();
for (var i = 0; i < sqlException.Errors.Count; i++)
{
errors.Add(string.Format("{0} - {1}", sqlException.Errors[i].Number, sqlException.Errors[i].Message));
}
throw new DbUpdateException(string.Join(Environment.NewLine, errors));
}
}
同时使用Sync和Async方法的一种方法是在Sync方法和Async方法中使用实际的逻辑来将前者封装到Task中。
public override Task<int> SaveChangesAsync()
{
return new Task(SaveChanges);
}
我最终使用委托(Func)解决了这个问题。下面是两个"duplicate". savechanges方法。
public override int SaveChanges()
{
return SaveChangesWrapper<int>(() => base.SaveChanges());
}
public override async Task<int> SaveChangesAsync()
{
return await SaveChangesWrapper<Task<int>>(async () => await base.SaveChangesAsync());
}
这是包装。
private T SaveChangesWrapper<T>(Func<T> function)
{
try
{
//do some work up front....
return function();
}
catch (DbEntityValidationException ex)
{
//parse exception and rethrow...
}
catch (DbUpdateConcurrencyException ex)
{
//parse and rethrow...
}
catch (DbUpdateException ex)
{
//parse and rethrow...
}
catch (Exception ex)
{
//parse and rethrow..
}
}