尝试在存储库中捕获

本文关键字:存储 | 更新日期: 2023-09-27 17:48:59

我所查看的Repository Patterns示例中没有一个包含任何类型的错误处理。为什么会这样?例如,我有这个:

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…如果不是在存储库本身中,这个错误处理应该在哪里?

尝试在存储库中捕获

在一个设计合理的系统中,约束不应该被违反。让你的实体更智能:例如,不要使用盲目的自动实现的setter。

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

  • 如果您只是检查"合同"约束,例如:"quantity应该是一个非负整数"或"不要传递给我一个空客户",将逻辑放在实体本身中(根据需要,可以是setter或构造函数或变异方法)。
  • 如果您正在检查业务逻辑,请将其放在抽象逻辑的专用对象(如果您愿意,可以使用DDD规范)中。
这些异常应该出现的唯一时间是当你运行单元集成测试时,你得到一个失败,这将揭示你的数据库约束与你的实体不匹配,或者你的实体实现不正确。所以你绝对不应该catch

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

例如,假设我们想要通过存储库插入一条记录,然后打印出新的ID。假设插入操作由于某种原因将会失败。
var myNewItem = myRepository.Insert(myItem);
Console.WriteLine("MyItem added with ID: {0}", myNewItem.ID);

按照您问题中的模式,如果Insert失败,您将在第二行获得NullReference异常。这有点奇怪。在第一行可以更清楚地看到DbUpdateException。如果能够指望Insert总是返回一个有效的实例或抛出一个异常,那就更好了。