2011-11-20 3 views
0

필자는 필자에게 필자가 필요로하는 특정 테이블의 데이터 행에 대해 몇 가지 훌륭한 감사 기능을 제공한다고 믿는 다음 클래스를 만들었습니다. 여기에 내가 사용하고있는 클래스는 다음과 같습니다Azure 테이블 스토리지에 행 추가 감사

public class AuditableTableServiceEntity : TableServiceEntity 
{ 

    protected AuditableTableServiceEntity() 
     : base() 
    { 
    } 

    protected AuditableTableServiceEntity(string pk, string rk) 
     : base(pk, rk) 
    { 
    } 
    #region CreatedBy and ModifiedBy 

    private string _CreatedBy; 
    [DisplayName("Created By")] 
    public string CreatedBy 
    { 
     get { return _CreatedBy; } 
     set { _CreatedBy = value; Created = DateTime.Now; } 
    } 

    [DisplayName("Created")] 
    public DateTime? Created { get; set; } 

    private string _ModifiedBy; 
    [DisplayName("Modified By")] 
    public string ModifiedBy 
    { 
     get { return _ModifiedBy; } 
     set { _ModifiedBy = value; Modified = DateTime.Now; } 
    } 

    [DisplayName("Modified")] 
    public DateTime? Modified { get; set; } 

    #endregion 

} 

거기에 사람이 내가이 클래스 고려할 수있는 추가 변경을 제안 할 수 있습니다. 나는 그것이 괜찮다고 믿는다. 그러나 많은 수업을 위해 이것을 구현할 필요가 있기 때문에 누군가가 어떤 변화 나 추가를 제안 할 수 있다면 듣고 싶다.

답변

4
private string _ModifiedBy; 

[DisplayName("Modified By")] 
public string ModifiedBy 
{ 
    get { return _ModifiedBy; } 
    set { _ModifiedBy = value; Modified = DateTime.Now; } 
} 

은 스택 오버 플로우를 일으킬 것 등 세터를 호출하고, 속성의 값을 설정 세터는 세터의 속성 값을 설정하는 통화.

생성자에서 속성을 설정할 수 있지만 인스턴스가 serialize 및 deserialize되면 문제가 발생합니다. 역 직렬화하면 public 매개 변수가없는 생성자가 호출되고 setter가 호출되어 ... 객체가 직렬화 된 날짜와 시간. 저장된 값이 아닙니다.


감사 이벤트를위한 다른 테이블을 만드는 것이 더 좋은 패턴 일 수 있습니다. 이것은 다음과 같이 보일 수 있습니다 당신은 당신이 감사 할 객체를 변경할 때마다

public class Audit 
{ 
    public string ModifiedBy { get; set; } 
    public DateTime DateModified { get; set; } 
    public Type ObjectType { get; set; } 
    public string Field { get; set; } 
    public object OldValue { get; set; } 
    public object NewValue { get; set; } 

    public static void Record(string user, Type objectType, object oldValue, object newValue) 
    { 
     Audit newEvent = new Audit 
     { 
      ModifiedBy = user, 
      DateModified = DateTime.UtcNow, // UtcNow avoids timezone issues 
      ObjectType = objectType, 
      OldValue = oldValue, 
      NewValue = newValue 
     }; 

     Save(newEvent); // implement according to your particular storage classes 
    } 
} 

을 그런 다음과 같이 Audit.Record() 전화 :

public class SomeKindOfAuditableEntity 
{ 
    private string _importantFieldToTrack; 

    public string ImportantFieldToTrack 
    { 
     get { return _importantFieldToTrack; } 
     set 
     { 
      Audit.Record(GetCurrentUser(), this.GetType(), _importantFieldToTrack, value); 
      _importantFieldToTrack = value; 
     } 
    } 
} 

당신이 모든 변경 사항의 로그를 저장하는이 방법이 테이블의 모든 "흥미로운"속성에 발생합니다.

  • 에게 필요하지 않은
    • 당신이, 감사 로그는 데이터 자체와는 다른 장소에 저장되어
    • 각 변경의 이전 및 새 값을 볼

      분리 문제
    • : 이것은 몇 가지 다른 장점이 있습니다 당신이 개체의 변경의 전체 로그를 통해 돌아갈 수 있도록
    • 된 변경에 대한 감사 주위에 보관 데이터 클래스에 대한 기본 클래스를 가지고하는 것은

    주요 단점은 코드를 추가 할 필요가 있다는 것입니다 관심있는 각 속성에 대한 각 설정 자에게 전달할 수 있습니다. 속성 및 반사 및 aspect 지향 프로그래밍을 사용하여이를 완화 할 수있는 방법이 있습니다. 예를 들어 여기의 Spring 구현 : http://www.springframework.net/doc-latest/reference/html/aop.html - 본질적으로 추적하려는 속성.

    또 다른 단점은 감사 로그를위한 많은 저장 공간을 사용한다는 것입니다. 그러나 적절하게 볼 때 오래된 항목을 주기적으로 줄이는 백그라운드 프로세스를 가질 수 있습니다.