8

我看过的Repository Patterns的例子都没有包含任何类型的错误处理。 这是为什么?举例来说,我有这个:试试看Catch

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 ...如果不在存储库本身中,这个错误处理将在何处生效?

回答

3

大部分情况下,存储库不需要担心处理异常。正在使用这些存储库的类应该处理该类。在你的例子中,为什么要在发生插入错误时返回null?这不是比抛出异常更清楚吗?

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

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

继在你的问题的模式,你会得到一个NullReference例外,在第二行,如果Insert失败。这有点奇怪。在第一行看到DbUpdateException更清楚。最好能够依靠Insert总是返回一个有效的实例或抛出一个异常。

+0

我没有问题抛出DbUpdate异常,它比我同意的NullRefrence更干净。回到sotred程序那天,我们会使用,如果不存在。很显然,我对数据模型持有不同的看法。那么如何使一个实体足够聪明,在插入之前检查记录? – 2011-04-06 04:08:13

+0

一种方法是在插入之前使用某种验证器来检查约束条件,以便提供友好的错误消息。或者你可以捕获数据库在任何使用版本库时抛出的约束异常。无论哪种方式,我不认为这是存储库的工作,以确定是否可以插入记录。 – rsbarro 2011-04-06 04:24:40

+0

我同意,当我完成存储库代码并实际为消费者连接一些DI时,我将穿越该桥。 – 2011-04-06 04:28:06

9

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

存储库不是做数据验证的地方。适当的地方是:

  • 如果您只是检查“契约”约束,例如“数量应该是一个非负整数”或“不要给我一个空客户”,将逻辑放在实体本身(适当的时候可以是setter或构造函数或变异方法)。
  • 如果您正在检查业务逻辑,请将其放入抽象出该逻辑的专用对象(如果您愿意,则使用DDD规范)。

唯一的一次,这些异常应该拿出是当你运行你单元集成测试,你会得到一个失败,这就会发现,无论是你的数据库的约束不匹配与你的实体,或您的实体正确实施。所以你绝对不应该catch他们。