2

감사 추적에 대한 몇 가지 게시물과 기사를 읽는 데 시간을 할애했지만 여전히이를 파악할 수 없습니다. 내가 필요로 무엇EF 4.2 코드로 가로 채기 및 로깅 변경

나에게 다음과 같은 결과를 줄 것이다 아주 기본적인 감사 시스템 :

고객 "홍길동은"
  • 고객 "신원 미상이"에 의해 만들어진
  • "사용자" "에 의해 삭제 된
    • 다른 사용자 신원 미상 "에서
    • 주소는"사용자 "에 의해 수정 된" "
    • 고객 "신원 미상는 다른 사용자 "

    I"에 의해 제거 " dbContext에 SaveChanges를 이벤트를 무시하려하지만 난이 다음과 같은 문제에 붙어있어 :

    public override int SaveChanges() 
    { 
    
         foreach (DbEntityEntry<IAuditable> entry in ChangeTracker.Entries<IAuditable>()) 
         { 
          if (entry.State == EntityState.Added) 
          { 
           // since the object was not added yet, if I write to log in here and 
           // for some reason SaveChanges fail, I will end up with a fake log entry 
          } 
          else if (entry.State == EntityState.Modified) 
          { 
           // same in here 
          } 
         } 
    
         return base.SaveChanges(); 
    
         // here the state for all entries have changed to Unchanged or Detached. 
         // detached is probably the one that was deleted however the “Unchanged” 
         // could be new or modified records. 
    } 
    

    나는 이러한 목표를 달성하기 위해 데이터베이스에 트리거를 사용할 수 있습니다 알고 있지만 나는 그래서 더 제어 할 수 있습니다 여기에 그것을 유지하고 싶습니다 그것 이후, 나는 SQL 녀석이 아니기 때문에 응용 프로그램을 배포 한 후에 db에 대한 많은 제어권을 가지지 않을 것입니다.

    나는 여기서 아주 간단한 것을 놓치고있을 것이라고 확신한다. 모든 도움에 감사드립니다.

    미리 감사드립니다.

    답변

    2

    컨텍스트에 감사 항목이 있는지 항상 확인하고 SaveChanges가 호출 될 때이를 제거 할 수 있습니다. 첫 번째 문제는 해결 될 것입니다. 새 감사문을 작성하기 전에 항상 이전 감사 항목을 제거합니다.

    두 번째 문제는 DbContext API로 해결할 수 없습니다. DbContext API는 ObjectContext API를 단순화 한 것으로이 단순화는 복잡한 시나리오에 필요한 메소드를 제거했습니다. 그러한 방법 중 하나는 SaveChanges의 오버로드 된 버전으로 변경 사항을 수락하지 않는 기능입니다 (엔티티의 상태는 변경하지 않음).

    DbContextObjectContext에서 IObjectContextAdapter으로 변환 할 수 있습니다. ObjectContext을 사용해도 직진하지 않습니다.

    // If you want to have audits in transaction with records you must handle 
    // transactions manually 
    using (TransactionScope scope = new TransactionScope(...)) 
    { 
        ObjectContext context = ((IObjectContextAdapter)this).ObjectContext; 
        context.SaveChanges(SaveOptions.DetectChangesBeforeSave); 
    
        var audits = new List<Audit>(); 
    
        // Now you must call your audit code but instead of adding audits to context 
        // you must add them to list. 
    
        // This is the reason why you must not add changes to context. You must accept 
        // old changes prior to adding your new audit records otherwise EF will perform 
        // changes again. If you add your entities to context and call accept before 
        // saving them your changes will be lost 
        context.AcceptAllChanges(); 
    
        // Now add all audits from list to context 
    
        context.SaveChanges(); 
    
        // Complete the transaction 
        scope.Complete(); 
    } 
    
    +0

    성능은 어떻습니까? DbContext를 ObjectContext로 캐스팅 한 후 데이터를 저장하는 속도가 느리지는 않습니까? – Saber

    +0

    @Saber : DbContext는 내부적으로 ObjectContext를 사용하므로 성능에 영향을 미치지 않아야합니다. –