2013-08-06 10 views
5

Ho una classe complessa (vedere il codice di esempio di seguito) salvata in un database Entity Framework First (V5). Il problema è che se FooClass viene utilizzato nei dati FooAndOrBar che vengono salvati nel database, voglio impedire che la voce FooClass venga cancellata. Poiché potrebbe essere nullo, i controlli delle chiavi esterne non impediranno l'eliminazione di FooClass, quindi devo verificarlo.ValidateEntity in Entity Framework non richiamato Cancellazione della voce

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; } 
    } 

Pertanto, a seguito di buone pratiche per la convalida le voci che tagliano su più voci di database, ho aggiunto un test per il metodo ValidateEntity di Entity Framework come illustrato di seguito.

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); 

    } 

Il problema è che ValidateEntity non sembra essere chiamato su delete. Questo ha senso (perché convalidare qualcosa che cancellerai), ma mi lascia il problema di dove dovrei mettere l'assegno? Io uso un pattern UnitOfWork/repository e potrei mettere un test lì dentro, ma quell'odore.

Qualcun altro ha incontrato questo problema e risolto in modo pulito? Il tuo contributo sarebbe apprezzato.

RISPOSTA DA Pawel (vedere sotto).

@pawel ha sottolineato che è possibile eseguire l'override di ShouldValidateEntity in modo che ValidateEntity venga chiamato per gli elementi eliminati. Ecco alcuni esempi di codice nel caso in cui qualcun altro lo trovi utile.

/// <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); 
} 

in realtà ho fatto l'assegno un po 'più stretto di appena tutti gli elementi eliminati di controllo per il tipo di entità, ma che è solo per migliorare le prestazioni.

+0

Inizialmente mi viene in mente l'azione di eliminazione nel controller. – nocturns2

risposta

11

Per impostazione predefinita, solo le entità modificate e aggiunte sono convalidate. Questo può essere modificato sovrascrivendo il metodo DbContext.ShouldValidateEntity() per restituire true anche per le entità eliminate.

+0

Ciao @pawel. Questo è esattamente ciò di cui avevo bisogno e ha funzionato perfettamente. Avrei potuto testare il codice che ho in DbContext per tenere traccia delle modifiche, ma quella convalida e il monitoraggio misto, che non è un'idea intelligente. Ho incluso un codice di esempio nella mia risposta. –

+0

Contento che funzioni per voi e grazie per aver aggiunto il codice per mostrare la soluzione. – Pawel

Problemi correlati