存储库模式:添加项目

时间:2010-05-11 23:39:52

标签: c# repository domain-driven-design

只需澄清一下,如果我有以下界面

public interface IRepository<T>
{
    T Add(T entity);
}

实现它时,如果实体已经存在之前检查重复是否仍然是存储库的一个工作,或者它应该处理其他地方?

3 个答案:

答案 0 :(得分:0)

如果实体已存在,您可以抛出异常,也可以更新现有实体的字段。

如果选择后者,该方法可能应该被称为AddOrUpdate()

Linq to SQL示例

如果我正在检索单个记录,我将使用

public Entity GetEntity(int entityID)
{
    return dataContext.Entities.SingleOrDefault(e => e.EntityID = entityID);
}

...在调用方法中,我将在尝试使用返回的实体之前检查返回的内容是否为null。

如果我正在更新记录,我将检索实体,如图所示,编辑实体,然后调用UpdateEntity(entityID)存储库方法来更新数据库中的字段。

如果我要添加记录,那就更容易了。由于这是一个数据库,并且我的表总是包含int类型的Identity字段(本质上是一个可自动赋值的数字),添加记录是所有操作中最简单的操作(它的总是一个新记录) :

Public void InsertEntity(Entity entity)
{
    dataContext.Entities.InsertOnSubmit(entity);
    dataContext.SubmitChanges();
}

业务规则(例如,电子邮件地址是唯一的)可以在存储库中处理,也可以在单独的业务层中处理。如果您正在寻找最“正确”的方式,我想大多数人会同意业务规则属于他们自己的业务逻辑层。

答案 1 :(得分:0)

是 - 我建议在存储库中执行这些检查。

长答案:术语“存储库”有点模糊,但它越来越多地被用作持久性抽象层的名称。名称很好,但并没有说太多:如果以Asp.Net MVC为例,示例应用程序(如Neirds晚餐等)或codeplex项目封装了存储库类的数据访问。如果使用关系数据库为instancce实现此类层,则表的主键将不允许重复条目,这意味着在这种情况下,如果插入具有相同键的2个条目,则存储库实现将引发异常。换句话说,存储库的RDBMS实现将始终由于此检查,您将无法避免它。因此,为了使世界上最重要的存档的行为存在,并避免意外,让他们所有人都做这个检查。

第二个问题是,您是否应该在业务逻辑中维护您的Add()方法未与已存在的条目相关联。有时,由于并发问题或往返的节省,仅在单个点(例如数据库)解决此问题是很有意义的。另一方面,例如,尽快告诉用户已经使用了用户名是很好的。所以这取决于。

度过愉快的一天

答案 2 :(得分:0)

基本上,处理该案件的决定取决于您的具体要求。

如果您有业务规则定义明确的切割操作,例如,如果存在重复项,则应重命名新项目,然后将其构建到存储库类中。

另一方面,如果有更复杂的规则,例如,在添加之前需要更多信息来更改项目,那么应该在食物链上进一步处理。

存储库的概念声明它存在以执行持久性活动。 所以如果你可以在存储库中完成所有操作,那很好。如果您发现您开始在存储库外部引用,或者您的存储库具有依赖关系,例如调用另一个存储库,服务或管理器(或您喜欢的任何处理器命名法),那么将其取回一步是一个好兆头。