I want to validate the graph of objects (from different but related entities) being saved with Entity Framework Core. In Entity Framework 6, the framework validates it at SaveChanges Operation. In EF Core, the docs says the validation is not performed automatically. So, in ASP MVC Core, we can use the ModelState.IsValid. But, i'm not using ASP MVC and i prefer to not depend on that very big framework.
Anyway, How I can validate models before SaveChanges in EntityFramework Core 2, without depending on full ASP MVC framework?
Yeah, looks like there is no out of the box validation. You can handle it by yourself by overriding SaveChanges
:
public class MyContext : DbContext
{
public virtual DbSet<Model> Models { get; set; }
public MyContext()
{
}
public override int SaveChanges()
{
var changedEntities = ChangeTracker
.Entries()
.Where(_ => _.State == EntityState.Added ||
_.State == EntityState.Modified);
var errors = new List<ValidationResult>(); // all errors are here
foreach (var e in changedEntities)
{
var vc = new ValidationContext(e.Entity, null, null);
Validator.TryValidateObject(
e.Entity, vc, errors, validateAllProperties: true);
}
return base.SaveChanges();
}
}
public class Model
{
[Key]
public int Id { get; set; }
[Required]
[MaxLength(32)]
public string Field { get; set; }
[Range(15, 25)]
public int RangeField { get; set; }
}
validateAllProperties
is important because without it you
won't get range validations.SaveChangesAsync
.This thing won't be really helpful if you set constraints with fluent syntax
, unfortunately. Actually, as fluent syntax
can possibly not only add new constraints, but also override existing, it's better to switch completely to attributes annotation, or find another way to make validation.