Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate all my entities composed two tables for each entity via a T4 automation

I have a class library project for a data access layer that uses Entity Framework 4. My project needs a versioning concept. My database contains many tables that contain «Id» and «CreationDateTime». Each table is associated with a version table that contains the detail. All Tables are constructed in the same manner and suffixed with «Version» for the version table.

I search for a way to generate all my entities (EF4 models) via a T4 automation that would unified Table and TableVersion (for the specified version) in one entity.

This unified Entity must support get, insert, update and delete operations.

Is it possible to do by modifying one of the T4 templates ? If it is, how ?

Thanks a lot for any pointers.

like image 853
ylegare Avatar asked Sep 21 '11 20:09

ylegare


1 Answers

Probably not what you are looking for, but you can check out this blog post where I made similar proof of concept for journaling/versioning database. I have not used T4 (that is why I think this is probably not what you are looking for, but you may not find better solution) and generated entities, but inherited all entities from one base entity which had versioning properties. Basically, I extended DbContext by overriding SaveChanges method, and set my versioning properties there:

foreach (var entry in this.ChangeTracker.Entries())
    {
        // Make sure that this customized save changes executes only for entities that
        // inherit from our base entity (IEntity)
        var entity = (entry.Entity as JEntity);
        if (entity == null) continue;
 
        switch (entry.State)
        {
            // In case entity is added, we need to set OriginalId AFTER it was saved to
            // database, as Id is generated by database and cannot be known in advance.
            // That is why we save reference to this object into insertedList and update
            // original id after object was saved.
            case System.Data.EntityState.Added:
                entity.UserCreated = user;
                entity.DateCreated = now;
                insertedList.Add(entity);
                break;
 
            // Deleted entity should only be marked as deleted.
            case System.Data.EntityState.Deleted:
                if (!entity.IsActive(now))
                {
                    invalidList.Add(entity);
                    continue;
                }
                entry.Reload();
                entity.DateDeleted = now;
                entity.UserDeleted = user;
                break;
 
            case System.Data.EntityState.Detached:
                break;
 
            case System.Data.EntityState.Modified:
                if (!entity.IsActive(now))
                {
                    invalidList.Add(entity);
                    continue;
                }
                entity.UserCreated = user;
                entity.DateCreated = now;
 
                JEntity newVersion = this.Set(entity.GetType()).Create(entity.GetType()) as JEntity;
                newVersion = this.Set(entity.GetType()).Add(newVersion) as JEntity;
                this.Entry(newVersion).CurrentValues.SetValues(entity);
 
                this.Entry(entity).Reload();
 
                entity.DateDeleted = newVersion.DateCreated;
                entity.UserDeleted = user;
                break;
            case System.Data.EntityState.Unchanged:
                break;
            default:
                break;
        }
    }

Link for full source code on github is in article.

This solution uses same table for current and past versions of entity, and I'm planning to improve this concept by trying to put all "deleted" versions of entities into separate table, which would be private on DbContext, and all logic for transfer of items to history would be on save changes. That way would allow exposed public dbset to contain only current versions of item, allowing for any dynamic-data-like generic solutions to be built on top of such context.

like image 109
Goran Obradovic Avatar answered Nov 05 '22 01:11

Goran Obradovic