Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 遵循DRY原则的业务规则验证_C#_Winforms_Entity Framework_Entity Framework 5 - Fatal编程技术网

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

C# 遵循DRY原则的业务规则验证,c#,winforms,entity-framework,entity-framework-5,C#,Winforms,Entity Framework,Entity Framework 5,Background-我通常使用DataAnnotation属性或通过实现IValidatableObject接口在实体类本身的属性级别执行验证。此代码通常无法访问DBContext 然后,我通常将更复杂的业务规则验证放在服务层。此类验证的示例包括:检查数据库中的值是否唯一,以及检查其他实体值。这些类确实需要DBContext来查询数据库 问题-我的问题是我最终在服务层重复了相同的代码。例如,当我插入并更新一个实体时,我重复相同的代码来检查给定的值是否唯一 我读过一些设计模式,比如约束、策略和规

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

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

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


我读过一些设计模式,比如约束、策略和规范。我想我只是需要一些帮助来把它们放在一个EF,分层的上下文中。非常感谢。

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

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

在验证ID是否唯一的实例中,您可以在存储库中添加一个名为GetById的方法,通过该方法传入要检查的实体的ID,如果该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!
    }
  }
}
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!
    }
  }
}
您的每个存储库都可以访问所管理的实体,例如Entity Framework中的ObjectSet(我想这就是所谓的ObjectSet),因此您可以在存储库中安全地放置特定实体上下文中的任何共享验证

例如:

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!
    }
  }
}
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逻辑。

当您必须转到数据库时,您需要使用DbContext,并且DbContext有一个名为ValidateEntity的可重写方法。请参阅本文:


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

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


您有repitories吗?嗯,当您使用
BaseRepository
时,问题似乎可以解决。