2013-08-06 57 views
5

我有一個複雜的類(請參閱下面的示例代碼),我將其保存在實體框架代碼優先數據庫(V5)中。問題是如果在保存到數據庫的FooAndOrBar數據中使用FooClass,我想停止刪除FooClass條目。因爲它可能是null,所以外鍵檢查不會阻止FooClass被刪除,所以我必須檢查自己。實體框架中的ValidateEntity未調用條目的刪除

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

因此,以下用於驗證跨多個數據庫條目削減項很好的做法,我加了一個測試,以實體框架的執行validateEntity方法如下所示。

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

    } 

問題是,ValidateEntity似乎沒有被調用刪除。這是有道理的(爲什麼要驗證你要刪除的東西),但留下了我應該把支票放在哪裏的問題?我確實使用了UnitOfWork/repository模式,並且可以在那裏進行測試,但是有異味。

有其他人遇到過這個問題,並以一種乾淨的方式解決它?您的意見將不勝感激。

帕維爾的答案(見下文)。

@pawel指出,您可以重寫ShouldValidateEntity,以便爲已刪除的項目調用ValidateEntity。以下是一些示例代碼,以防其他人發現它有用。

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

我實際上通過檢查實體的類型使檢查比只刪除所有項目更緊一點,但這只是爲了提高性能。

+0

最初它讓我想到控制器中的刪除操作。 – nocturns2

回答

11

默認情況下,只有修改和添加的實體纔會生效。這可以通過覆蓋DbContext.ShouldValidateEntity()方法來改變,也爲被刪除的實體返回true。

+0

Hi @pawel。這正是我所需要的,並且完美運作。我可以在DbContext中用於跟蹤更改的代碼中進行測試,但混合驗證和跟蹤不是一個聰明的想法。我在我的答案中包含了示例代碼。 –

+0

很高興它爲您工作,並感謝您添加代碼以顯示解決方案。 – Pawel