12

I'm building a windows application in .Net 4.0 to create and organize electronics projects. The main purpose of the application is to record the vendor information for the electronics components (part #, description, price, etc.) and organize (associate) them into projects (finished products). One of the requirements is to track changes for any given vendor item (mainly price) and changes at the project level to provide a point-in-time statistics at both component level and project level details for changes.

I decided to use Entity Framework 4 for my data access layer with SQL CE 3.5 for the database, given the simplicity of client deployment. The data access works great, but when attempting to create the relationships (associations) between objects, the framework doesn't appear to have any obvious way to use historical data. This is my first attempt at using the entity framework, so I figured it might just be my inexperience that's keeping me from finding the answer. Here's my basic schema:

I have 3 main tables: Project, Product, and ProjectProduct

The Project and Product tables each have an ID column and a DateAdded column which are used as the complex key. The ProjectProducts table has the IDs for each of the other two tables and maintains the many-to-many relationships between the entities. The relationship table also has a DateAdded column to track changes in the product / project associations.

While the Entity Framework seems to work great with maintaining associations that are direct (no date criteria) using the standard code-generated data objects, it's a bit confusing on how to get it to load the associations for a point-in-time historical data schema. Essentially I need to be able to load the data objects based on the date criteria for the point-in-time requirements (parametrized loading).

Has anyone done anything similar and can point me in the right direction?

Sorry for the long explanation, but thanks in advance for any help you can provide!

Glen
  • 203
  • 2
  • 10

1 Answers1

10

I implemented the exact same thing. It's pretty easy with EF4. You basically handle the OnSavingChanges event, and enumerate the set of changed items, storing them as you please.

The only problem is, it is VERY tricky to get inserted items (unless you are ok with not having a Primary Key of the new item, which I was not) I decided to only track updates and deletes.

This article shows you how to do it, though my implementation was a lot simpler (I didn't like storing changes in XML so I made a separate table for columns)

Implementing Audit Trail using Entity Framework - Part 1

part 2 shows how to do rollbacks, if you are interested in that.

Implementing Audit Trail using Entity Framework - Part 2

Neil N
  • 24,862
  • 16
  • 85
  • 145
  • Hi Neil - First of all, great articles on using the EF with audit trail records. However, that doesn't exactly match my historical snapshot record scenario (different historical type). I'm thinking I may need to create another layer of objects that inherit from the data objects and manage the snapshot relationships in code. I don't know that EF can handle historical relationships in this manner, but perhaps someone can prove me wrong. – Glen Jul 06 '11 at 17:11
  • Glen - then in your case, I would create an archive version of each table, and insert snapshot items instead of into a generic history table. That way you can maintain relationships between the tables. – Neil N Jul 06 '11 at 17:30
  • Just be sure to add timestamps to each archive table to allow for propert point-in-time querying – Neil N Jul 06 '11 at 17:31
  • Thanks Neil. I'm looking at the archive table scenario as a possibility. I'm pretty sure that if I was using a SQL technology that supports stored procedures (which CE does not), then I could use the SP parameters to handle the historic data and return the snapshot objects accordingly. My other option is to not have EF handle the relationships, and instead use another layer of objects inheriting the data objects and manage the relationships in code. In any case, many thanks for the suggestions. – Glen Jul 06 '11 at 17:53
  • Great info in those links. I've seen a solution previously that turned out identical results using stored procs, but that was always a giant pain to deal with. – edsobo Jan 16 '13 at 16:57