bilal-fazlani / tracker-enabled-dbcontext

Tracker-enabled DbContext offers you to implement full auditing in your database
https://tracker-enabled-dbcontext.bilal-fazlani.com/
Other
217 stars 110 forks source link

Changed Table name to TypeFullName breaks physical logging naming #65

Open banban opened 8 years ago

banban commented 8 years ago

In version 3 you have changed audit table AuditLogs field TableName to TypeFullName. I think it was bad idea. AuditLogs should reflect real table name, not application entity full name. Entity name does not provide value from database perspective. For example, [TrackChanges] [Table("dbo.TableName")] public partial class EntityName {}

Is it possible to configure logger to write TableName (like it was in version 2.7) defined in model attribute rather than TypeFullName like Namespace.Models.EntityName ?

bilal-fazlani commented 8 years ago

I have realised that different people want different things so I will have to provide some configuration where devs can specify what do they want to log. I will work on it. Also, feel free to contribute to it.

bilal-fazlani commented 8 years ago

By the way, have you looked at this : How to upgrade from version 2.7 to 3.0 ?

It makes it easy for you to upgrade without any manual work.

banban commented 8 years ago

Just imagine that you have 2 applications changing the same table. How can you see changes applied by one app inside another app? The only way is to track it by table name, not by class name. Ideally you need both to show which application changed that record. But key field is table name

mgildea commented 8 years ago

If you are using a TPH schema you couldn't even tell which type of object was changed if the tablename was used instead of the class full name. The whole idea of EF is to work with objects not tables. With full class name you can rebuild your object at any point in time regardless of if your underlying schema has changed over time.

I do see how an additional property in AuditLog may be useful to accommodate this with some sort of application name/context name along with the user identity, time stamp, etc....to give context to the user and the env performing the change...

Just a few quick thoughts about this topic

Matt

banban commented 8 years ago

Sorry Matt, But you can easily translate TypeFullName into TableName. All you need is to read Table Name attribute shown above, by passing through the view Model.GetType().BaseType (as parameter entityType). Here is example:

var customAttributes = entityType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false);
string tableName = entityType.Name;
if (customAttributes.Count() == 0)
{
           customAttributes = entityType.BaseType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false);
           tableName = entityType.BaseType.Name;
 }
if (customAttributes.Count() > 0)
{
          tableName = (customAttributes.First() as System.ComponentModel.DataAnnotations.Schema.TableAttribute).Name;
}

My point is - table AuditLogs should track both TableName and TypeFullName fields. Using only TypeFullName does not grantee that many apps (referencing and sharing the same source table for different entities) can collaborate effectively.

mgildea commented 8 years ago

I never said you couldn't determine the table from the type, but that you couldn't determine the type from the table....but ya I don't think there is anything wrong with storing the table name along with the type

bilal-fazlani commented 8 years ago

@banban , @mgildea if you guys agree to storing both table and type full name, what is your opinion about columns,

should we store column names, property names , or both ?

banban commented 8 years ago

Good point Bilal, I think you need both of them. I understand that looks slightly denormalized. But both of keys could change over time (which can cause another issue ). And it is good trade-off decision.

Ideally, in your case, Table-Entity, Field-Property mapping should be stored in separate table to avoid global changes over time. Look at my project https://virtualdb.codeplex.com . It has additional metadata tables (Entity and Field) which are never stored in data tables (Row, Value) but have references by RowId, FieldId. It is a little be different approach, but you can get the idea.

Again, you can keep both keys in your structures (Entity-Table, Property-Field) allowing to query log data from data or code perspective. Any changes within model or data would not dramatically affect on existing logs if you have at least one key value which you can use to update another one..