背景 - 我通常使用DataAnnotation
属性或通过实现IValidatableObject
接口在实体类本身的属性级别执行验证。此代码通常无法访问DBContext
。
然后,我通常在服务层中放置更复杂的业务规则验证。这些验证的示例包括:检查数据库中的值是唯一的,以及检查其他实体值。这些类确实需要DBContext
来查询数据库。
问题 - 我的问题是我最终在服务层重复相同的代码。例如,当我插入并更新实体时,我重复相同的代码以检查给定值是否唯一。
我阅读了有关设计模式,例如约束,策略和规范。我想我只需要一些帮助就可以将它们组合在一个EF,分层的上下文中。非常感谢。
答案 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)
感谢您的回答,他们非常有见地。我认为这篇文章恰当地回答了我的问题。非常感谢。