2013-04-03 39 views
0

我有以下我的应用程序: 行动奥姆实体(从Telerik的开放式接入),当我需要保存一个实例 库(行动) AppService服务(存放在仓库的一个实例)验证功能应该直接访问存储库吗?

,我送实例到AppService。 AppService然后调用验证器来验证要保存的实例。验证是基于http://codeinsanity.com/archive/2008/12/02/a-framework-for-validation-and-business-rules.aspx (上https://github.com/riteshrao/ncommon完整的代码)

所以基本上我保存功能在AppService服务看起来像这样

Public Sub AddAction(ByVal Item As Data.Model.Action) 
     Contract.Requires(Of ArgumentNullException)(Item IsNot Nothing, "Item is nothing.") 

     Dim validateResult As Rules.ValidationResult = _ActionValidator.Validate(Item) 
     If Not validateResult.IsValid Then 
      Throw New Validation.ValidationException(validateResult) 
     End If 

     Try 
      _ActionRepository.Add(Item) 
      _unitOfWork.SaveChanges() 
     Catch ex As Exception 
      _unitOfWork.ClearChanges() 
      Throw New DataServiceException(ex.Message, ex) 
     End Try 

    End Sub 

检查行动项目的示例代码的伟大工程的性质。我的问题开始时,我需要确保相同的行动没有添加两次到数据库为同一个客户(即身份证是差异,名称是相同的,客户是相同的)

因为我看到它我有几个选项: 选项1:使用类似

function(validatedItem) item.Customer.Actions.Any(function(item) item.id<>validatedItem.id andalso item.name=validatedItem.name)) 

基本上我从行动去被保存返还给客户,然后回到他的一切行动检查是否有重复的动作,并检查是否有任何行动存在不同的ID和相同的名称

down si des是:

a。为此,在访问该项目的客户属性时,将从DB中读取整个客户对象,在这种情况下,这是冗余的 b。任何函数都在客户端上评估为item.Customer.Actions返回IList(Of Action)

选项2:让验证类可以访问操作存储库。那么我可以简单地这样做

'assume I already have validatedItem 
repository.Any(function(item) item.id<>validatedItem.id and item.customerid=validatedItem.customerid and item.name=validatedItem.name) 

这将导致一个EXISTS查询被发送到数据库但下行(?)是验证框架不应该直接访问存储库(据我所看到的在极少数例子中,我可以发现使用验证和ORM)

选项3:让验证类有权访问AppService并使用AppService检查是否存在重复。问题: a。我创建了一个循环引用(AppService-> Validation Class-> AppService) b。我需要在AppService中创建许多无用功能,用于根据仅与验证相关的条件加载项目

任何想法这里最好的课程是什么?

回答

2

最简单的办法就是不要从域中检查数据库中的重复项。

当实体的集合是你的一部分时,那么这是一个非问题,因为你不允许将重复添加到集合中。由于聚合是作为一个整体存储的,所以你永远不会遇到问题。

对于您不希望重复(例如电子邮件地址)且实体的集合没有由集合表示(例如系统中的Users)的场景,您可以让数据库强制执行唯一性。只需拿起例外并回报。在许多情况下,您的验证将无法完成唯一性,因为它没有/实现数据库系统所需的锁。

所以我只是简单地将直接留给数据库。