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

2

17

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.

Intellectualize answered 21/9, 2011 at 20:45 Comment(2)
What have you tried? Can you give example code explaining what your existing tables are outputting, and what you'd like them to output? Can you give an example of your schema, so we can tell if you want a single table, multiple tables, shared tables? If you can get this far in defining your requirements, it is pretty easy to modify templates to do what you want, since you get instant feedback on your code generation every time you save... Also, which development approach are you taking? Code first, model first, DB first? Table per class, table per hierarchy, etc....Asphyxiant
You have some of these details, but they're not very clear since this question is in "word problem" style, rather than having concrete code/schema examples. Also, T4 Templates won't help in every scenario I mentioned.Asphyxiant
P
1

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.

Polloch answered 2/10, 2011 at 17:41 Comment(0)
C
0

T4 templates can generate interface and attributes to "mark" your entities. After that, you can build generic classes to provide consistent policies or behaviors against your entities.

Your question is very interesting. I will try to build an example for your case using the T4 templates in https://entityinterfacegenerator.codeplex.com

Commissary answered 10/5, 2014 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.