遵循DRY原则的业务规则验证

时间:2013-06-15 17:17:40

标签: c# winforms entity-framework entity-framework-5

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

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

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

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

3 个答案:

答案 0 :(得分: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逻辑。

答案 1 :(得分:1)

当你必须转到数据库时,你需要使用DbContext,而DbContext有一个名为ValidateEntity的Overridable方法。请参阅此文章:Entity Framework Validation

我将我使用的代码放在另一个答案here

答案 2 :(得分:0)

感谢您的回答,他们非常有见地。我认为这篇文章恰当地回答了我的问题。非常感谢。

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