次の方法で共有


AttachAsModified revisited

It seems like on a fairly regular basis these days I encounter a question or an issue about the EF to which the answer is “I know I wrote a blog post about that…”  Then when I go search my blog and find the post I discover that the post was written before EF4 and things are now a lot easier than they used to be.  Here’s another one of those situations:

About a year ago I wrote a post presenting a little extension method AttachAsModified which was designed to make a few small n-tier scenarios easier to write by hand.  You can read the post for more background on the situation, but the issue which came up today is that in EF4 the code in that post can be made much simpler.  The hardest part of the code before was iterating over an object’s properties and telling the ObjectStateManager to mark each property as modified.  It wasn’t all that many lines of code, but it was pretty obtuse.  The reason for this code is that the ObjectStateManager had two relevant methods—one marks the whole entity as modified but not any of its properties, and the other marks a single property as modified.  What was missing was something that would set all of the properties to modified, and the trick for that was to use metadata from the EF to get the list of persisted property names.

As part of our effort to improve n-tier support in general for EF4, though, we added the method ChangeObjectState to ObjectStateManager, and if you use that method to change an object’s state to “Modified”, then it will do the work of mark each property as modified for you.  So my AttachAsModified method becomes trivial—just one call to attach the entity and another call to change its state.

In addition, the earlier version of this method actually had two overloads—one for the case where your entity implemented IEntityWithKey so it could use the key to Attach the entity and another which did not require that interface but did require you to supply the EntitySet name.  With the introduction of ObjectSet<T> this can be further simplified because we can just add our AttachAsModified extension method to ObjectSet<T> and remove the need for the overload which takes an entityset name while still supporting a method signature that does not require IEntityWtihKey.  Even better, the signature is strongly typed to match the type of the set so you get nicer intellisense support.

The final code for the new method is just:

 public static void AttachAsModified<T>(this ObjectSet<T> objectSet, T entity) where T : class
{
    objectSet.Attach(entity);
    objectSet.Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}

At this point the whole extension method seems pretty superfluous, which I guess is the goal of improving the EF in the first place.  :-)

- Danny

Comments