【发布时间】:2018-08-11 01:16:48
【问题描述】:
我通常通过调用 entity.IsValid() 并为实体创建适当的 ValidationAttribute 类来验证实体框架中的实体。
但是,现在我遇到了一个案例,我不仅需要验证实体,还需要在它所属的上下文中验证实体,例如:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class CourseValidation : ValidationAttribute
{
public CourseValidation() {}
protected override ValidationResult IsValid (object value, ValidationContext validationContext)
{
List<string> messages = new List<string>();
if (value is Course)
{
Course course = (Course)value;
if (course.Context != null)
{
if (course.Context.Courses.Any(c => c.Name == course.Name && c.Department.ID == course.Department.ID))
{
messages.Add($"Cannot create a course with name {course.Name} in {course.Department.Name} department because a course with this name already exists in this department.");
}
}
else messages.Add("Course is being improperly handled by the software, please contact support department");
}
else messages.Add("Course is expected, but does not exist");
if (messages.Count > 0) return new ValidationResult(string.Join(Environment.NewLine, messages));
else return ValidationResult.Success;
}
}
有一个困难:简单地使用context.Courses.Add(course) 不会导致context.Courses.Where(c => c.Name == course.Name) 返回任何东西。相反,它需要context.SaveChanges() 才能将实体作为整个集合的一部分使用。这意味着在尝试将实体保存到数据库之前,我将无法针对集合验证实体。
我知道这个示例很简单,可以通过数据库端唯一约束来处理,但即使我们不打算查看更复杂的示例,我也有充分的理由在尝试提交之前过滤无效条目它们到数据库(因为如果事务中的一个条目违反约束,整个事务将被阻止),并将所有验证标准放在一个地方,而不是在不同的类和/或数据库模式之间拆分它们(以维护单一责任)。
可以通过哪些方式实施验证策略来满足这些要求?
【问题讨论】:
标签: c# .net entity-framework validation