【问题标题】:Repository Pattern : Add Item存储库模式:添加项目
【发布时间】:2010-05-11 23:39:51
【问题描述】:

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

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

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

【问题讨论】:

  • @Alastair Pitts,这是否意味着检查唯一字段也是存储库工作的一部分?

标签: c# repository domain-driven-design


【解决方案1】:

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

长答案:“存储库”一词有点含糊,但它越来越多地用作持久性抽象层的名称。名字很好听,但不多说:如果以 Asp.Net MVC 为例,Neirds Dinner 之类的示例应用程序或 codeplex 项目封装了存储库类的数据访问。如果这样的层是用关系数据库实现的,则表的主键将不允许重复条目,这意味着在这种情况下,如果插入具有相同键的 2 个条目,存储库实现将抛出异常。因此,换句话说,存储库的 RDBMS 实现总是会进行此检查,您将无法避免它。因此,为了使世界上存储库的行为最相似并避免意外,让所有存储库都进行此检查。

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

祝你有美好的一天

【讨论】:

    【解决方案2】:

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

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

    Linq to SQL 示例

    如果我要检索一条记录,我将使用

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

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

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

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

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

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

    【讨论】:

    • 这正是我的问题。检查实体是否存在(如果存在,则抛出异常,否则 AddOrUpdate)是存储库的工作吗?
    • 是的,但是。如果规则规定您只能输入/推送唯一字段,例如(用户名和电子邮件),“添加记录是所有操作中最简单的操作(它始终是新记录)”不是真的。所以你只能插入一次“sample@domain.com”的电子邮件。
    • 啊,是的,我想你会这么说。业务规则(如您所描述的)可以在存储库中执行,如果您需要额外的间接层,也可以在单独的业务逻辑层中执行。
    • @No Body,如果您有几个不是主键的唯一字段,那么您需要在另一点进行检查。正如 Rob Harvey 所提到的,您可以在存储库中执行此操作,阻止 Add() 或在此之前,这样一开始就不会调用 Add()。我有一些代码可以在另一台计算机上执行此操作,我会尽快发布。
    • @Alastair Pitts,这是否意味着检查唯一字段也是存储库工作的一部分?
    【解决方案3】:

    基本上决定在哪里处理该案件取决于您的确切要求。

    如果您的业务规则为发生这种情况定义了明确的操作,例如,如果存在重复项,则应重命名新项目,则可以将其构建到存储库类中。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-23
      • 2014-01-07
      • 2016-07-25
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多