Note that there are some explanatory texts on larger screens.

plurals
  1. POKeeping A Record of Changes to Entity Framework object
    text
    copied!<p>I'm writing a software which receives person information from various sources and all this data is stored into database. The tricky part is when this information is combined to master records. This combining is implemented as a pipeline of different kinds of steps which update the master record from the information received from sources. All steps implement a common interface <code>IPersonUpdatingStep</code> which has <code>Update(Person person)</code> method.</p> <p>I would like to keep a record about which updated fields and especially about which step was responsible for the change. Different steps might update the same field and I'm only interested in the last change which is present after the master record has traveled through the whole pipeline.</p> <p>My first instinct was to take a deep copy of the object when it enters a step and another deep copy after it returns and make a diff based on these copies. However deep copying an object of a class which is generated with Entity Framework's Database First tools seems to be quite difficult. It would be quite easy if shallow copies were enough but I need to know if any of the related entities stored in collections were changed.</p> <p>One suggested easy solution for deep copying was to serialize and deserialize an object but as the model is autogenerated based on database, I cannot add these Serializable attributes.</p> <p>The problem is even more difficult because the object has related entities and collections of related entities so I need to know if some step changed some properties of these related collection entities.</p> <p>I wouldn't want to change the pipeline steps so that each would contain code like this:</p> <pre><code>if (targetPerson.FirstName != sourcePerson.FirstName) { targetPerson.FirstName = sourcePerson.FirstName; changes.Add("FirstName", "Name of the step responsible for the change"); } </code></pre> <p>But is there another readable and reliable option? I am aware of how I could write an audit trail with Entity Framework when I'm saving the object to database but at that stage I can only log which properties were changed whereas I'm more interested in what pipeline step was responsible for changing the field.</p> <p>I feel like I'm not doing anything so groundbreaking that others wouldn't have run across this same problem.</p> <p><strong>UPDATE:</strong> haim770's suggestion about ChangeTracker API was a good one. I managed to get information about changed basic properties but how to get information about changed relationships? For example, my <code>Person</code> object has one-to-many relationship with <code>Address</code> objects. I would like to get the information not only about which <code>Address</code> object was updated but even more specifically, which property of that <code>Address</code> object was changed.</p> <pre><code>DbEntityEntry entry = _source.Context.Entry(person); foreach (var property in entry.Entity.GetType().GetProperties()) { DbMemberEntry propertyEntry = entry.Member(property.Name); if (propertyEntry is DbPropertyEntry) { var foo = propertyEntry as DbPropertyEntry; if (foo.IsModified) { changes.Add(step.GetType().Name + ": " + property.Name); } } // How to handle relationships? } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload