0

我的应用程序中有以下内容:Action Orm 实体(来自 Telerik 开放访问)Repository(Of Action)AppService(保存存储库的实例)

当我需要保存实例时,我将实例发送到 AppService。AppService 然后调用验证器来验证要保存的实例。验证器基于http://codeinsanity.com/archive/2008/12/02/a-framework-for-validation-and-business-rules.aspx (完整代码在https://github.com/riteshrao/不常见

所以基本上我在 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

为了检查操作项的属性,示例代码效果很好。我的问题开始于我需要确保同一客户的同一操作不会两次添加到数据库中(即 id 不同,名称相同且客户相同)

正如我所看到的,我有几个选项: 选项1:使用类似的东西检查重复操作

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

基本上,我从保存的操作返回给客户,然后返回到他的所有操作,并检查是否存在具有不同 ID 和相同名称的任何操作

缺点是:

一个。为此,当访问项目的客户属性时,从数据库中读取整个客户对象,这在这种情况下是多余的 b。正在客户端上评估 Any 函数,因为 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 检查是否存在重复项。问题:一。我创建了一个循环引用 (AppService->Validation Class->AppService) b。我需要在 AppService 中创建许多无用的函数,以根据仅与验证相关的条件加载项目

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

4

1 回答 1

2

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

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

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

所以我只是把留给数据库。

于 2013-04-04T05:14:00.817 回答