N-Tier Methods in Entity Framework 4 – Use with Care

One of the things I struggled with in n-Tier apps in EFv1 was the options for reconstructing entity state on the server side in order to call SaveChanges when modified data was passed in from the client.

The options were to hit the database to get a set of current server values and then apply updates to those or to just attach the incoming data and iterate through each property marking it as modified so that SaveChanges would be able to construct an Update.

The problem with the former was the extra hit to the database. That made me crazy.

The problem with the latter is that I was marking every property as modified even when they weren’t and that made me crazier. Admittedly not really worse than the first.

If you’ve seen the WCF chapter in my book, you’ll know I opted for the extra database hit.

In EF4, there are new state methods. In addition to ApplyPropertyChanges (from v1) being renamed to ApplyCurrentValues and acquiring a sibling, ApplyOriginalValues, there is the ChangeState method. I explored the impact of these methods in my Sept/Oct 2009 CoDe Magazine article, What’s New in Entity Framework 4? Part 1: API Changes .

I want to focus now on using ChangeState to set an entity to Modified.

This is similar to walking through each property and marking it modified. The concept is that you are saying “this entity is modified” without having to specify exactly what was modified. Every property is marked as modified and every property will be included in an update statement.

But what if every property was not supplied?

What if you have a client app that allows users to edit a few fields of a contact record. And…the client app is a website which means that when the user hits a Save button and the page posts back, there’s no original contact object. So in order to save, in one layer or other, some code constructs a contact to return to the server/repository. Here’s the code:

Contact c = new Contact {ContactID= Convert.ToInt32(IDLabel.Text),
        FirstName = TextBox1.Text, LastName = TextBox2.Text,
        ModifiedDate = DateTime.Now, State = State.Modified };

I have a state property in there because this is a POCO object and I can put whatever I want in it. 🙂 Plus I use the state property to help me out when I get to the server side.

Looks okay, but what if I told you there is also a Title property in this class?

Because the UI developer didn’t populate that value, on the server, the assumption will be that Title is null. When you call ChangeState(EntityStateModified), that null will be seen as the value to be used for the update. Take a look at part of the update method sent to the database. It’s setting Title=null.

exec sp_executesql 
N'update [dbo].[Contact] set [FirstName] = @0, [LastName] = @1, [Title] = null, [ModifiedDate] = @2 where...

This is not to say that there’s anything wrong with the ChangeState method (or ApplyCurrentValues/ApplyOriginalValues, which will do the same thing). THe point (as always) is that you really need to be aware of what’s going on.

My worry is that I can’t really control what’s happening on the consumer side. It’s such a critical rule. I don’t want to “solve” it by making all of my properties non-nullable. (Can you imagine? 🙂 )

So it means that I have to think carefully about how and where I use these methods because I may not always have control of the state of what’s being passed in.

I was getting accustomed to the idea of just marking all of the properties modified and living with the inefficient update. One inefficient trip to the database is more cost effective than two trips to the database.

There’s always the CACHING option. But that gets really sticky with multiple users and graphs and lazy loading etc. I know I can cache my POCOs, even my graphs, or just values if I want… easily enough. I was just hoping to avoid that extra layer for now.

So I either have to make the consumer cross-their-heart-and-hope-to-die-promise to return the entire object back to me with the correct values or I have to go back to using some of the options from EFv1 – hit the database, manually (and selectively) mark each properites as modified or pass original values around.

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

12 thoughts on “N-Tier Methods in Entity Framework 4 – Use with Care

  1. What I suggest (and I did) is to add a List<string> ModifiedProperties in the ObjectChangeTracker class. Then in the set of properties you can fill it.

    Now, of course, the best way is to add it in the T4 template directly (what I did).

    Matthieu

  2. Wouldn’t the Self Tracking Entities template solve this problem? Or have you already decided against using it for some other reason?

  3. btw, the point of the posts is to be a heads up on what to expect when using the n-tier methods. There are defintily other ways to skin the proverbial cat. 🙂

  4. I’m testing EF4. (I come from typed dataset). I encountered many problems with "disconnected" object and Optimistic concurrency ON (ConcurrencyMode=Fixed). I got OptmisticConcurrencyException whe I use Attach + ChangeObjectState + SaveChanges.

    Why EF(4) is harder to use than TypedDataSet? Ok, it’s more powerful it lacks in a good support of optimistic concurrency in a N-tier scenario. IMHO.

  5. Can someone please explain to me why "STEs are for WCF only. We still have web apps and other n-tier apps to deal with on our own." We are using them in a web project and I’m curious to know what’s wrong with it, before we go to production. Thanks!

  6. Like Andrew, I’ve been experimenting with STEs without WCF. My final solution will use WCF as the service tier, but since I’m still in development, I don’t need to expose it as such. Not yet, anyway.

    You definitely need to flip the bit on ChangeTrackingEnabled or you’ll scratch your head when nothing updates. So far, it seems to be a nice solution.

    I’m still not certain that STEs will be something I want to deploy everywhere, but when I control all tiers and consumer (as I do in this current project) it seems the best choice for that.

    Also, as I’m using MVVM and binding to the object in question, I have less concern about the UI not exposing a value… for updates. I suppose I’m still just as concerned about inserts.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.