EF Code-First inherit a single base class to implement easy historocity

后端 未结 1 554
粉色の甜心
粉色の甜心 2020-12-12 01:32

I am running into some errors implementing my plan as described below. I am not so interested at this point in resolving particular errors as I am in whether or not this is

相关标签:
1条回答
  • 2020-12-12 02:05

    I think you will need the full-qualified-name of the object's type when desalinizing, so that will be mandatory.

    Alternatively serializing the object will be cause you problems.
    Assume that we are going to audit TacoOject1 of Taco class using the approch, the serialized data will be put in data base, later due to business changes we need to add another property to Taco, after recompilation when we need to deserilazed TacoOject1 we will get TypeMissMatchException (not sure of exception name).

    Another design objection is using inheritance for audit process.
    First: In reality Taco is not a AuditableObject , Its a roll played by Taco, using inheritance will violate Liskov Substitution Principle.
    Second: You can not use multiple inheritance, think that if we had a TacoSupperClass, how we could audit Taco then?

    If I where going to design auditing process, I would use Entity–attribute–value model
    Making AuditItem a marker interface and rename it to IAuditableEntity.
    Having an attribute called AuditableProperty would enhance our process.
    Any entity needs to be audited will be marked by IAuditableEntity, any property of the entity needed to be partcipated in audit will be marked by AuditableProperty attribute.

    public class Taco : IAuditableEntity 
    { 
      [AuditableProperty]
      public string Seasoning { get; set; } 
    
      [AuditableProperty]
      public string OtherProperty1 { get; set; } 
    
      public string OtherProperty2 { get; set; } 
    
    }
    

    The AuditLog table will have these columns:
    1. EntityFullTypeName: (String) We are going to audit different entities, the field will be used to get meaningful reports .(mandatory)
    2. ObjectIdentifier: Entity identifier that is being manipulated, primary key or business key of the entity.
    3. FieldName: (String) Entity field name.
    4. OldValue: (String) Entity field old value.
    5. NewValue: (String) Entity field new value.
    6. TransactionUser: Application user that makes the change. (mandatory)
    7. TransactionID: Any operation changing the entities will need to have a unique transaction ID (like GUID) (mandatory), In case of an update on an entity changing multiple fields,these column will be the key point to trace all changes in the update(transcation)
    8. ChangeDate: Transaction date. (mandatory)
    9. FieldType: enumeration or text showing the field type like TEXT or Double. (mandatory)

    In service layer when Taco1 is going to be updated(or inserted) we will check if Taco1 type is marked by IAuditableEntity using reflection(using a lazy chash to store reflection data), if so which properties have been changed(we need a separate DB call to fetch old values).
    e.g :

    Taco1 = new Taco(); 
    Taco1.Seasoning = "old Seasoning value";
    Taco1.OtherProperty1 = "Old Other Property1 value";
    Taco1.OtherProperty2 = "Old Other Property2 value";
    

    Saved before,now updating:

    Taco1.Seasoning = "New Seasoning value";
    Taco1.OtherProperty1 = "New Other Property1 value";
    Taco1.OtherProperty2 = "New Other Property2 value";
    

    We will insert two records in AuditLog with the same TransactionID:

    enter image description here

    Having this approach
    Any entity (table) could be traced
    Reports will be readable
    Only changes will be logged.

    0 讨论(0)
提交回复
热议问题