Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ValidateEntity in Entity Framework not called on Delete of entry

I have a complex class (see example code below) that I save in an Entity Framework Code First database (V5). The problem is if a FooClass is used in the FooAndOrBar data that is saved to the database I want to stop the FooClass entry from being deleted. Because it could be null then the foreign key checks won't stop FooClass being deleted so I have to check myself.

    class FooClass { ... some properties }

    class BarClass { ... some properties }

    class FooAndOrBar
    {
        public int Id { get; set; }
        public FooClass Foo { get; set; }
        public BarClass Bar { get; set; }
    }

Therefore, following good practice for validating entries that cut across multiple database entries, I added a test to Entity Framework's ValidateEntity method as shown below.

    protected override DbEntityValidationResult ValidateEntity(
        DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if (entityEntry.Entity is FooClass && 
            entityEntry.State == EntityState.Delete)
        {               
            if (... entityEntry.Entity is used in DbContext.FooAndOrBars ...)
                return new DbEntityValidationResult(... error ...);
        }

        return base.ValidateEntity(entityEntry, items);

    }

The problem is that ValidateEntity does not seem to be called on delete. That makes sense (why validate something you are going to delete) but leaves me with the problem of where should I put the check? I do use a UnitOfWork/repository pattern and could put a test in there, but that smells.

Had anyone else come across this problem and solved it in a clean way? Your input would be appreciated.

ANSWER FROM Pawel (see below).

@pawel pointed out that you can override ShouldValidateEntity so that ValidateEntity is called for deleted items. Here is some example code in case someone else finds this useful.

/// <summary>
/// Override ShouldValidateEntity to cause deleted entities to be checked as well
/// </summary>
protected override bool ShouldValidateEntity(DbEntityEntry entityEntry)
{
    if (entityEntry.State == EntityState.Deleted)
        return true;

    return base.ShouldValidateEntity(entityEntry);
}

I actually made the check a bit tighter than just all deleted items by checking for the type of the entity, but that is just to improve performance.

like image 606
Jon P Smith Avatar asked Aug 06 '13 15:08

Jon P Smith


1 Answers

By default only modified and added entities are validated. This can be changed by overriding the DbContext.ShouldValidateEntity() method to return true also for deleted entities.

like image 181
Pawel Avatar answered Oct 05 '22 11:10

Pawel