LINQ-To-SQL: Updating Disconnected Entity Objects

| 2 Comments | No TrackBacks

Here’s the skinny:  Don’t get into a situation where you have to update an object from a disconnected DataContext.  You will fail, and miserably.

Sure, you can do some Googling and find some resources on the subject, and even find some slightly tolerable solutions.. but even those require some nasty stuff, some hard coding of methods in the DataContext class itself, and/or adding versioning field to your database table.

Google:  “linq disconnected updates” and “LINQ Update Disconnected Entity Objects”

The best solution that I found, that worked for me – was a bit more of tightly coupling what was happening, and passing around an open DataContext from start-to-finish through the various methods.

It seems to me that the best way would be something hypothetical like this:

[your]DataContext.Update<[YourTable]>([YourEntityObject]);
[your]DataContext.SubmitChanges();

Of course, that “Update” method doesn’t exist, only the “Attach” method that seems like it should do what we want, but doesn’t really.  The “Update” method of course, would update using only the primary key of the entity to perform the update.  I suppose I see why this might not exist due to complications with child entity objects.

The other alternative AFAIK is to create a CopyFromEntityToEntity extension method or class method to copy from the object you wish to update, to an object acquired from the database during the update method.  Something like the following:

//Warning, this is pseduo-code and will not work for various reasons and should be a generic method.  This also assumes the PK is a GUID[uniqueidentifier] field.  There is no error checking, etc.
void Update(orders_mainTable updateEntity, Guid identifier) {
  myDataContext dc = new myDataContext();
  
  var original = dc.Table.Where(o => o.Guid == identifier).SingleOrDefault();
  if (original == null)
    throw new Exception(“Original Entry in Database Not Found.”);

  // Some Extension Method?
  original.CopyFrom(updateEntity);

  // Update the database
  dc.SubmitChanges();
}

The CopyFrom method would iterate over the reflected values of the objects and copy the data from the “updateEntity” object to the original object.  This way, you’re not going to run into any issues issuing an update to a 'disconnected’ object.

Good luck!  This one sure makes me mad though.. LINQ-to-SQL should be smart enough to take care of this for [us] automatically in my opinion.  This is going to be a huge issue for n-tier disconnected architectures.  Instead of being able to fully take advantage of X,Y,Z those portions that do the updating will have to go through hoops like the example above to be able to update something.

Note:  My example above does not address child objects that may be stored along with the entity.

P.S.  I absolutely love LINQ [with the exception of this!].  I had to re-write a substantial part of the application I am working on after some major database changes for features requested by the client.. well, I made a decision to replace portions of code that were already written that needed to be update with LINQ-To-SQL stuff.. and wow!  I was able to write the new LINQ-based code with more features than the original code had.. and implement it faster than I would have been able to modify the existing code to update it to the new requirements. 

Wow.

Further Reading: 

Rick Strahl has some interesting information on this topic as well but offers some more detail in the suggestions such as adding a timestamp field, etc.
Link:  LINQ to SQL and Disconnected Entities Follow-up

Omar Al Zabir has some ideas as well.
LINK:  Linq to SQL: How to Attach object to a different data context

Here are some other generic Google results that I found during research:
http://msdn.microsoft.com/en-us/bb546187.aspx

http://geekswithblogs.net/michelotti/archive/2007/12/30/118076.aspx

http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/6f42d725-4540-4044-be86-afc7bc2d2b46/

http://stackoverflow.com/questions/273578/linq-to-sql-disconnected-updating-object-from-different-data-context

Thanks!

Matthew MacSuga

No TrackBacks

TrackBack URL: http://www.csharpbydesign.com/cgi-bin/mt/mt-tb.cgi/29

2 Comments

Dude here is the solution to your problem, it drove mad at first too ;)

///
/// Update an Existing Object
///
/// The type of the instance we want to update
/// The object to update
public void Update(T instance) where T : class
{
using(var data = new GenericDataContext(_connectionString))
{
var table = data.GetTable();
table.Attach(instance);
data.Refresh(RefreshMode.KeepCurrentValues, instance);
data.SubmitChanges();
}
}

Happy coding :)

Have you given this a try? http://www.codeplex.com/LINQ2SQLEB

I just found it and will be trying it out myself, but wondered if anyone else has given it a shot.

Leave a comment

About this Entry

This page contains a single entry by Matthew M. published on February 9, 2009 10:31 PM.

LINQ-to-SQL – Love it, or Hate It was the previous entry in this blog.

Reflection based IEnumerable<T> TrimAll() function is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.