只需澄清一下,如果我有以下界面
public interface IRepository<T>
{
T Add(T entity);
}
实现它时,如果实体已经存在之前检查重复是否仍然是存储库的一个工作,或者它应该处理其他地方?
答案 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)
基本上,处理该案件的决定取决于您的具体要求。
如果您有业务规则定义明确的切割操作,例如,如果存在重复项,则应重命名新项目,然后将其构建到存储库类中。
另一方面,如果有更复杂的规则,例如,在添加之前需要更多信息来更改项目,那么应该在食物链上进一步处理。
存储库的概念声明它存在以执行持久性活动。 所以如果你可以在存储库中完成所有操作,那很好。如果您发现您开始在存储库外部引用,或者您的存储库具有依赖关系,例如调用另一个存储库,服务或管理器(或您喜欢的任何处理器命名法),那么将其取回一步是一个好兆头。