【问题标题】:should a validation function access the repository directly?验证功能是否应该直接访问存储库?
【发布时间】:2013-04-03 14:11:23
【问题描述】:

我的申请中有以下内容: Action Orm 实体(来自 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

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

在我看来,我有几个选择: 选项 1:使用类似的方法检查重复操作

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

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

缺点是:

一个。为此,在访问项目的客户属性时,会从数据库中读取整个客户对象,在这种情况下是多余的 湾。 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) 湾。我需要在 AppService 中创建很多无用的函数,用于根据仅与验证相关的标准加载项目

你知道这里最好的课程是什么吗?

【问题讨论】:

    标签: validation orm domain-driven-design ddd-repositories


    【解决方案1】:

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

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

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

    所以我只是将那个留给数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-04
      • 2020-02-24
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多