【问题标题】:How should I design this? Nhibernate unit of work in a method我应该如何设计这个?方法中的休眠工作单元
【发布时间】:2011-10-20 21:15:29
【问题描述】:

我正在使用 asp.net mvc 和 nhibernate 与工作单元模式。

我有这样的事情

public bool IsSomething()
{
   unitOfWork.BeginTransaction();
   var myGetStuff = repo.GetStuff(1);

   if(myGetStuff == null)
   {
       return false;
   }  

   var somethingElse = myGetStuff.GetSomethingElse();

   if(somethngElse == null)
   {
      return false;
   } 

   return true;
}

因此,在我的 if 语句中,如果某些内容为 null 并且我需要它不为 null,我就退出该语句。

这与嵌套 if 语句相反,它可能像嵌套 4 或 5 次一样进行空值检查。

public bool IsSomething()
{
   unitOfWork.BeginTransaction();
   var myGetStuff = repo.GetStuff(1);

   if(myGetStuff != null)
   {
      var somethingElse = myGetStuff.GetSomethingElse();

       if(somethngElse != null)
       {
          // some more check heere ( could have another few if statements null checks here)
       } 
   }  
}

所以我发现第一种方法比 if 语句的嵌套级别更容易阅读。

我的问题是,即使您在 nhibernate 中执行查询,您必须将其包装在事务中,最后执行回滚或提交。

选项 1

  public bool IsSomething()
    {
       unitOfWork.BeginTransaction();
       var myGetStuff = repo.GetStuff(1);

       if(myGetStuff == null)
       {
           unitOfWork.Commit();
           return false;
       }  

       var somethingElse = myGetStuff.GetSomethingElse();

       if(somethngElse == null)
       {
        unitOfWork.Commit();
          return false;
       } 

       unitOfWork.Commit();
       return true;
    }

我不喜欢这种方式,因为你必须在任何地方都提交。如果可能的话,我希望只有一个提交(除非我有多个工作单元事务)

那么我为什么不把它放在最后这样的地方

  public bool IsSomething()
    {
     try
     {
           unitOfWork.BeginTransaction();
           var myGetStuff = repo.GetStuff(1);

           if(myGetStuff == null)
           {
               return false;
           }  

           var somethingElse = myGetStuff.GetSomethingElse();

           if(somethngElse == null)
           {

              return false;
           } 

           return true;
       }
       catch(Exception ex)
       { 
          unitOfWork.RollBack();
       }
       finally
       {
          unitOfWork.Commit();
       }
    }

我喜欢这个,但后来我意识到如果提交失败会发生什么?它不会回滚,也不会捕获异常。

那么其他人有什么想法吗?

【问题讨论】:

  • 您是只阅读还是同时更新/插入?
  • 取决于方法,有些可能混合了读取/更新/插入,或者有些可能只是读取。

标签: c# .net nhibernate unit-of-work


【解决方案1】:

你的这段代码在我看来相当有问题,尤其是当有嵌套的工作单元调用时(你如何处理这些调用?)。我要做的是在调用代码(您使用 ASP.Net MVC 时的控制器)而不是 IsSomething 函数中打开工作单元(和事务)。它看起来像这样:

try
{
    unitOfWork.BeginTransaction();
    // some code
    var isSomething = IsSomeThing()
}
catch(Exception ex)
{ 
   unitOfWork.RollBack();
}
finally
{
    unitOfWork.Commit();
}

IsSomething 函数看起来就像这样

public bool IsSomething()
{
   var myGetStuff = repo.GetStuff(1);

   if(myGetStuff == null)
   {
      return false;
   }  

   var somethingElse = myGetStuff.GetSomethingElse();

   if(somethngElse == null)
   {

       return false;
    } 

    return true;
}

【讨论】:

  • 我不确定嵌套的工作单元是什么。这是我确实想过但不确定的事情。 IsSomething 在我的所有业务逻辑所在的服务层中。我设置了我的服务层,使其位于它自己的项目中,并尝试尽可能独立于 mvc,以便我可以采用该项目并在不同的项目中使用它(比如 web 服务)。因此,如果它与服务层一起使用,而不是我将其设为 .dll,然后突然之间您必须将其包装在 UoW 中,那就太好了。然后我不确定 UoW 是否应该放在控制器中?
  • 如果您需要多个事务,那么您的场景中会发生什么?
  • 我所说的嵌套工作单元的含义如下:您有一段代码(假设是一个控制器)。在开始时,您进行 UoW.BeginTransaction() 调用,最后是 UoW.Commit。然后在这个控制器中调用你的 IsSomething 函数,它也有一个 UoW.Commit。这不会干扰您的第一个 UoW.BeginTransaction 吗?我所做的是我总是在 http 模块中启动、提交和回滚我的事务。
  • 多笔交易,我没有。我总是将我的控制器建模为具有单个事务范围。
  • 好吧,因为我的想法是在控制器中不应该知道任何关于数据库的东西,我不应该遇到嵌套问题。我可以在我的服务层中有一个控制器调用的方法并调用一些私有方法。这可能是一种选择。就像我说的还没有在控制器中出售。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多