【问题标题】:Try Catch in Repository在存储库中尝试 Catch
【发布时间】:2011-04-06 03:32:34
【问题描述】:

我看过的存储库模式示例中没有一个包含任何类型的错误处理。 为什么是这样?比如说我有这个:

public virtual TItem Insert<TItem>(TItem item) where TItem:class,new()
    {
        dbContext.Set<TItem>().Add(item);
        try
        {
            dbContext.SaveChanges();
        }
        catch (DbUpdateException)
        {

            return null;
        }

        return item;

    }

我们违反约束的实例。我捕获了 DbUpdateException...如果不在存储库本身中,此错误处理将在哪里进行?

【问题讨论】:

    标签: c# entity-framework-4 domain-driven-design ddd-repositories


    【解决方案1】:

    在设计合理的系统中,永远不能违反约束。让您的实体更智能:例如,不要使用盲目的自动实现的设置器。

    存储库不是进行数据验证的地方。正确的地方是:

    • 如果您只是检查“合同”约束,例如“数量应该是一个非负整数”或“不要给我一个空客户”,将逻辑放在实体本身中(设置器或构造器或变异方法,视情况而定)。
    • 如果您正在检查业务逻辑,请将其放入抽象出该逻辑的专用对象(如果您愿意,可以使用 DDD 规范)。

    这些异常应该出现的唯一时间是当您运行 unit 集成测试并且失败时,这将表明您的数据库约束与您的实体不匹配,或者您的实体是实施不正确。所以你绝对不应该catch他们。

    【讨论】:

      【解决方案2】:

      在大多数情况下,存储库不需要担心处理异常。使用存储库的类应该处理这个问题。在您的示例中,如果发生插入错误,为什么要返回 null ?这不是比仅仅抛出异常更清楚吗?

      例如,假设我们要通过存储库插入一条记录,然后打印出新的 ID。假设插入将因任何原因失败。

      var myNewItem = myRepository.Insert(myItem);
      Console.WriteLine("MyItem added with ID: {0}", myNewItem.ID);
      

      按照您问题中的模式,如果Insert 失败,您将在第二行收到NullReference 异常。这有点奇怪。在第一行看到DbUpdateException 就更清楚了。最好能够依靠 Insert 始终返回有效实例或抛出异常。

      【讨论】:

      • 我对它抛出 DbUpdate 异常没有意见,它比我同意的 NullRefrence 更干净。如果不存在,我们将使用 sotred 程序日。显然我对数据模型有限制。那么如何让实体足够智能,以便在插入之前检查记录?
      • 一种方法是在插入之前使用某种验证器来检查约束,以便提供友好的错误消息。或者,您可以在使用存储库的任何内容中捕获数据库抛出的约束异常。无论哪种方式,我认为确定是否可以插入记录不是存储库的工作。
      • 我同意,当我完成存储库代码并实际为消费者连接一些 DI 时,我将跨过那座桥。
      猜你喜欢
      • 1970-01-01
      • 2014-12-22
      • 2017-06-12
      • 2012-02-26
      • 2017-02-13
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      相关资源
      最近更新 更多