2012-04-24 4 views
0

IValidatableObject.Validate는 구현 엔티티 DbEntityEntry.State가 "변경되지 않음"과 다른 경우에만 호출됩니다. 탐색 속성을 변경해도 상태가 변경되지 않으므로 유효성 검사가 수행되지 않습니다.IValidatableObject는 EF 탐색 속성에 쓸모가 없습니까?

Microsoft는 항상 반쯤 구운 베타 버전을 출시하는 이유는 무엇입니까?

난 손으로 탐색 속성의 변화를 감지 할 수 없습니다

var changes = context.ChangeTracker.Entries() 
    .Where(e => e.State != EntityState.Unchanged) 
    .ToArray(); 

는 하늘의 배열을 돌려줍니다.

답변

5

여기에 몇 가지 흥미로운 점이 있습니다. EntityFramework는 엔티티 변경에 독립적으로 탐색 속성의 변경 내용을 추적합니다. context.ChangeTracker.Entries()는 관계가 아닌 엔티티에 대한 변경 사항 만 반환합니다. 이것이 당신이 이것을 보지 않는 이유입니다. 당신은 정말 관계를보고 싶지 그들이 변경 방법은 다음 ObjectContext를 아래로 드롭 할 수있는 경우 :

var objectContext = ((IObjectContextAdapter) ctx).ObjectContext; 
foreach(var relationshipEntry in objectContext.ObjectStateManager 
               .GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted) 
               .Where(e => e.IsRelationship)) 
{ 
    EntityKey entityKey1, entityKey2; 

    if (relationshipEntry.State == EntityState.Added) 
    { 
     entityKey1 = (EntityKey)relationshipEntry.CurrentValues[0]; 
     entityKey2 = (EntityKey)relationshipEntry.CurrentValues[1];    
    } 
    else 
    { 
     entityKey1 = (EntityKey)relationshipEntry.OriginalValues[0]; 
     entityKey2 = (EntityKey)relationshipEntry.OriginalValues[1];       
    } 

    var entity1 = objectContext.GetObjectByKey((EntityKey)entityKey1); 
    var entity2 = objectContext.GetObjectByKey((EntityKey)entityKey2); 
} 

당신이 당신을 다시 확인해야 할 때이다 나에게 더 흥미 시나리오 엔티티가 변경 될 때 나는 당신이 외래 키를 가지고 있지 않다고 가정합니다. 그렇지 않으면 네비게이션 속성 변경으로 인해 변경된 것으로 표시 될 것입니다. 외래 키의 값이 바뀌면 엔티티가 수정 된 것으로 표시됩니다. 어쨌든 3 개의 유효 엔티티가 있다고 가정하면 - 변화하는 관계로 인해 엔티티 (또는 모델)가 무효화 될 수있는 시나리오는 무엇입니까? 또한 자체 유효성 검사는 주어진 엔터티 만 유효성 검사를하지만 탐색 속성을 따라 관련 엔터티를 확인하지 않습니다. 당신이 정말로 관계가 내가 생각 변경할 때 실체를 확인해야하는 경우 마지막으로 당신은 4 가지 옵션이 있습니다 : 변경 관계 (면책 조항을 수정 된 엔터티를 표시해야 외래 키를 변경할 수 있도록 외부 키를 추가

  • 시도 : I 시도하지 않았 음)

  • DbContext.ShouldValidateEntity() 메서드를 재정 의하여 모든 요소를 ​​수정 한 것 (여기서는 필터링 논리가 발생하는 곳) 대신에 유효성을 검사합니다. 성능에 약간의 부정적인 영향을 미칠 수 있습니다. 당신이 수정 된 모든 기관과 모든 개체에 대한 유효성 검사를 호출 할 수 있도록

 protected override bool ShouldValidateEntity(DbEntityEntry entityEntry) 
     { 
      return (entityEntry.State & EntityState.Deleted) == 0; 
     } 
  • 재정의 DbContext.SaveChanges() : 여기 DbContext에서 파생 된 클래스에 추가해야합니다 코드입니다 위의 코드를 사용하면 추가 된 관계 항목에만 관심이있을 가능성이 높습니다.

  • 모음을 수정하면 수동으로 해당 항목이 수정 된 것으로 표시됩니다. 그렇게 당신은 그냥 모두 삭제 엔티티

당신은 여기에서 확인 및 검증 사용자 정의에 대한 자세한 정보를 찾을 수 확인하기 훨씬 저렴 수 있습니다 추적 얼마나 많은 개체에 따라 데이터베이스에 불필요한 업데이트를 전송이 발생할 수 있습니다 : http://blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx (예 : CTP 및 EF 4.1에 해당하지만 창고가 보관함)

+0

많은 관계가 있다면 어떻게됩니까?나는 다음과 같은 비지니스/오브젝트 규칙을 가지고있다 : 부울 속성 A가 참이면 콜렉션 B는 비어서는 안된다. 이 부분이 객체 수준 유효성 검사의 일부가 아닌가? 다른 장소에서해야합니까? – springy76

+0

BTW : 이제 외래 키가 추가되었으므로 ObjectStateManager는 더 이상 관계 항목을 반환하지 않습니다. (엔터티 자체, 더 정확하게 외래 키 속성이 예상대로 변경된 것으로 표시됩니다.) – springy76

+0

1- *는 매우 흥미로운 시나리오입니다. 그 이유는 컬렉션에 엔티티를 추가하고 제거하는 것이 '1'측 (즉, 프린시 펄)의 엔티티에 실제로 영향을 미치지 않는다는 것입니다. 데이터베이스를 보면 해당 테이블에는 엔티티에 대한 외부 키가 없습니다. 관련 엔티티가 존재할 지 모릅니다. 그러나 관련 테이블에는 프린시 펄을 가리키는 외래 키가 추가되거나 제거되는 행이 있습니다 (다른 방법은 없습니다). 값이 수정되지 않으면 교장이 정말로 수정 되었습니까? – Pawel

관련 문제