是否可以从内部包装带有恒定代码的方法?

时间:2018-07-17 11:00:02

标签: c# .net entity-framework-6

我有很多数据库查询,希望将它们包装在相同的try-catch样式错误处理程序中。尝试保持代码干燥,我认为这样做是有效的,但是我找不到类似的东西。还有其他方法还是可以做到这一点?

我想制作一个这样的外部方法:

try
{
    // I would like to put any method here
}
catch (DbEntityValidationException)
{
    // Error handling
}
catch(DbUpdateException)
{
    // Error handling
}
catch (InvalidOperationException)
{     
    // Error handling
}
    catch (EntityException)
{
    // Error handling
}

在“ //我想在这里放置任何方法”的地方,我想放置这样的方法:

public DatabaseResultEnum DoSmth(int someId)
{
    using ( var context = new TestingDatabaseEntities() )
    {
        // Any database action
    }
}

只需调用内部(“ DoSmth()”)方法而不是在第一个方法中添加操作,然后像下面的示例那样将参数传递给它,将非常方便:Generic Function wrapper

谢谢!

2 个答案:

答案 0 :(得分:5)

是的,有可能。

public T DoSomething(Func<TestingDatabaseEntities, T> func)
{
    try
    {
     using ( var context = new TestingDatabaseEntities() )
        {
            // Any database action
            return func(context);
        }
    }
    catch (DbEntityValidationException)
    {
        // Error handling
    }
    catch(DbUpdateException)
    {
        // Error handling
    }
    catch (InvalidOperationException)
    {     
        // Error handling
    }
    catch (EntityException)
    {
        // Error handling
    }
}

然后食用:

public DatabaseResultEnum DoSmth(int someId)
{
    return this.DoSomething(context => context
               .DatabaseResultEnum.FirstOrDefault(y => y.Id == someId));
}

答案 1 :(得分:5)

使用委托。

因此,调用方将使用如下代码:

result = ExceptionChecker((context) => {
           // do something with the DbContext context
           return results...
         });

您在那里拥有的地方

IEnumberable<TRes> ExceptionChecker<TRes>(Func<MyDbContext,IEnumerable<TRes>> function) {
  try {
    using (var ctx = new MyDbContext(...)) {
      return function(ctx);
    }
  } catch (InvalidOperationException) {
    // Handle...
  } // etc.
}

当然,实际代码应使用async / await以避免阻塞长时间运行的查询中的线程。理想情况下,您可以更好地管理上下文实例,以利用EF对工作单元模式的支持(例如,每个Web请求具有单个上下文),在这种情况下,将DbContext实例传递给帮助程序。但这说明了方法。