2

背景- 我通常在实体类本身的属性级别执行验证,使用DataAnnotation属性或通过实现IValidatableObject接口。此代码通常无法访问DBContext.

然后,我通常将更复杂的业务规则验证放在 Service 层。此类验证的示例包括:检查一个值在数据库中是否唯一,以及检查其他实体值。这些类确实需要DBContext查询数据库。

问题- 我的问题是我最终在服务层中重复了相同的代码。例如,当我插入和更新一个实体时,我会重复相同的代码来检查给定值是否唯一。

我阅读了一些设计模式,例如约束、策略和规范。我想我只需要一点帮助就可以将它们放在一个 EF 分层上下文中。非常感激。

4

3 回答 3

1

当您必须访问数据库时,您需要使用 DbContext,并且 DbContext 有一个名为 ValidateEntity 的 Overridable 方法。请参阅这篇文章:实体框架验证

我把我在另一个答案中使用的代码放在这里

于 2013-06-17T08:05:33.240 回答
1

我会将验证保留在实体级别。在这里您可以检查是否设置了所需的属性,它们的值是否正确,您还可以比较实体上的属性。这确保了实体,无论其他实体如何,都处于有效状态。

在服务层中,您可以通过调用 Validate 方法来验证传递给该方法的任何实体,您还可以与数据库中的实体进行比较。

在验证 ID 是否唯一的实例中,您可以在存储库中添加一个名为 GetById 的方法,通过该方法您传入要检查的实体的 ID,如果它返回 NULL,则您没有找到具有该 ID 的实体因此它是独一无二的。

例如:

public class MyRepository
{
  public MyEntity GetById(int id)
  {
    return _entitySet.FirstOrDefault( item => item.Id == id );
  }
}

public class MyService
{
  public void ServiceMethod(Entity entity)
  {
    if( _repository.GetById( entity.Id ) == null)
    {
      // entity.Id is unique!
    }
    else
    {
      // entity.Id is not unique!
    }
  }
}

您的每个存储库都可以访问被管理的实体,例如实体框架中的 ObjectSet(我认为它被称为),因此您可以安全地将任何共享验证(在特定实体的上下文中)放在存储库上。

例如:

public class MyRespository
{
    public bool IsIdUnique(int id)
    {
      Entity entity = _entitySet.FirstOrDefault( item => item.Id == id );
      return entity == null ? true : false;
    }
}

public class MyService
{
  public void ServiceMethod(Entity entity)
  {
    if( _repository.IsIdUnqiue(entity.Id) )
    {
      // entity.Id is unique!
    }
    else
    {
      // entity.Id is not unique!
    }
  }
}

您还可以将 GetById 添加到上面的 MyService 类中,并调用 IsIdUnique 方法,而不是重新键入 lambda。这样您就可以重用 GetById 逻辑。

于 2013-06-15T17:54:12.563 回答
0

谢谢你的回答,他们非常有见地。我认为这篇文章正确地回答了我的问题。非常感激。

http://msdn.microsoft.com/en-us/data/gg193959.aspx

于 2013-08-29T01:59:17.593 回答