I’m using Entity Framework pretty heavily these days and have come to like it. There are a few tricks to using it, but in general it get the job done. One of the tricks I’ve been developing with help from Robert Hinojosa is a CodeSmith template to add some extra functionality to our entity model. We started off just adding some validation stuff, but it is slowly growing.
Adding IEditableObject
The first problem is that I need to add some interfaces to all of the entities. The important interface is IEditableObject. There are several ways to add this interface, but in this case I have to keep in mind that most of the object is generated by VisualStudio’s EF designer. All IEditableObject does is hold on to a backup copy of the object so that you can roll back your changes. The easiest way I can see to get it done is to just make a private instance of the object in the class and then copy the properties.
Coping the object properties inside a CodeSmith template is easy enough. The schema explorer object provides the information you need. You just have to make sure that you are not coping columns that are foreign keys. Other than that it is a cake walk.
Two other ways to do the same thing:
Paul Stovell demonstrates using the memento design pattern. The trick here is that you keep the object’s state in a separate container that can be copied. This pattern makes implementing multi-level undo a snap. Just keep an ordered collection of state containers. The problem here is that VS doesn’t generate the entities in a way that would make this easy to do.
The other option is to stuff the entity in a memory stream. This would probably work pretty well, but I have questions about memory consumption. If the entity has references to other objects do those get pulled in to the stream too? This approach would be super easy to generate in a template though. I might have to go back and test it out to see what happens.
Regenerate without losing customizations
Once I get the template cleaned up the way I want it I have another issue. Our database is still being developed and is continuing to change. That means I have to be able to easily regenerate my DAL and entity objects (one and the same in this case) quickly and without having to go hand code stuff back in. That means I need a way for code smith to generate from my template without overwriting changes in the files.
Code Smith provides merge strategies to handle this situation. The InsertRegion strategy will work for my template. The only problem is that it means that I’ll have to keep two version of my template (for now). The first version is run if the file doesn’t already exist and does the initial generation for my library. Once the file exists the second template will handle generating just the one region that will contain my generate code.
If I do it right we’ll be able to regenerate the entity library in a minute or two after each change to the database without breaking too many things in the application. Once I finish this little project I’ll provide a sample to demonstrate the trick.
The two posts demonstrate what I’m talking about:
· Tips & Tricks: Merge Strategies – from Eric Smith’s blog
· CodeSmith merge functionality for csproj files - Miha Markic’s blog
The online help explains the two build in strategies:
· InsertRegion – inserts the template output into a specific region of the file
· PreserveRegion – saves regions of customization but lets CodeSmith generate most of the file