EF Core не вызывает ValidationException - PullRequest
0 голосов
/ 06 января 2019

У меня есть базовый DbContext класс, как

public abstract class DbContextBase : DbContext
{
    public DbContextBase()
    {
    }

    public DbContextBase(DbContextOptions options)
        : base(options)
    {
    }

    public override int SaveChanges()
    {
        this.ValidateEntities();

        return base.SaveChanges();
    }

    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        this.ValidateEntities();

        return base.SaveChangesAsync(cancellationToken);
    }

     public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
     {
        this.ValidateEntities();

        return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }

    protected virtual void ValidateEntities()
    {
        var entities = this.ChangeTracker.Entries().
                            Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);

        foreach (var entity in entities)
        {
            var validationContext = new ValidationContext(entity);
            Validator.ValidateObject(entity, validationContext);
        }
    }
}

Все мои классы Db Context наследуются от этого базового класса. Проблема в том, что строка Validator.ValidateObject() не выбрасывает ValidationException даже при нарушении проверки. В отладчике я вижу, что эта строка выполнена. Например, для класса ниже модели я пытаюсь вызвать SaveChangesAsync() с Name, установленным в null, но проверка проходит:

public class MyModel : IEntity<long>
{
    [Key]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }
}

IEntity<T> просто накладывает свойство Id на все модели.

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Проблема в том, что переменная entity не содержит экземпляр сущности, а изменяет экземпляр отслеживания (EntityEntry), поэтому код пытается проверить неправильную вещь.

Поэтому переименуйте переменные и используйте entry.Entity свойство:

var entries = this.ChangeTracker.Entries()
    .Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);

foreach (var entry in entries)
{
    var validationContext = new ValidationContext(entry.Entity);
    Validator.ValidateObject(entry.Entity, validationContext);
}

или оставьте код как есть, но убедитесь, что в переменной entities содержится множество экземпляров сущности:

var entities = this.ChangeTracker.Entries()
    .Where(s => s.State == EntityState.Added || s.State == EntityState.Modified)
    .Select(s => s.Entity); // <--
0 голосов
/ 06 января 2019

Код

public class MyModel : IEntity<long>
{
    [Key]
    public long Id { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string Name { get; set; }
}

Подробнее

...