Linq to SQL: How to Attach object to a different data context

After upgrading to Visual Studio 2008 RTM, you will have trouble updating Linq to SQL Classes which are read from one data context and then updated into another data context. You will get this exception during update:

System.NotSupportedException: An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.  This is not supported.

Here's a typical example taken from a Forum post:

   1: public static void
UpdateEmployee(Employee employee)
   2: {
   3: using (HRDataContext dataContext =
new HRDataContext())
   4: {
   5: //Get original employee
   6: Employee originalEmployee =
dataContext.Employees.Single(e=
>e.EmployeeId==employee.EmployeeId);
   7:  
   8: //attach to datacontext
   9:
dataContext.Employees.Attach(employee, originalEmployee);
  10:  
  11: //save changes
  12: dataContext.SubmitChanges();
  13:  
  14: }
  15: }

When you call the Attach function, you will get the exception mentioned above.

Here's a way to do this. First, create a partial class that adds a Detach method to Employee class. This method will detach the object from it's data context and detach associated objects.

   1: public partial class Employee
   2: {
   3:   public void Detach()
   4:   {
   5:     this.PropertyChanged = null;
this.PropertyChanging = null;
   6:  
   7:     // Assuming there's a foreign
key from Employee to Boss
   8:     this.Boss = default(EntityRef
<
Boss
>);
   9:     // Similarly set child objects
to default as well
  10:  
  11:     this.Subordinates =
default(EntitySet
<
Subordinate
>);
  12:   }
  13: }
  14:  
  15:  

Now during update, call Detach before attaching the object to a DataContext.

   1: public static void
UpdateEmployee(Employee employee)
   2: {
   3:     using (HRDataContext
dataContext = new HRDataContext())
   4:     {
   5:         //attach to datacontext
   6:         employee.Detach();
   7:  
   8:        
dataContext.Employees.Attach(employee);
   9:         //save changes
  10:  
  11:        
dataContext.SubmitChanges();
  12:     }
  13: }
  14:  

This'll work. It assumes the employee object already has its primary key populated.

You might see during update, it's generating a bloated UPDATE statement where each and every property is appearing on the WHERE clause. In that case, set UpdateCheck to Never for all properties of Employee class from the Object Relational Designer.

Published Saturday, December 08, 2007 12:59 PM by omar
Filed under: ,

Comments

# re: Linq to SQL: How to Attach object to a different data context

Saturday, December 08, 2007 8:53 AM by Andreas

Hi omar,

out of curiosity, are you using linq in any big projects so far?

Best Regards,

Andreas

# re: Linq to SQL: How to Attach object to a different data context

Saturday, December 08, 2007 6:20 PM by jdn

I have an Address object, which has an AddressType object, a state object, and a country object.  These child objects are loaded through Get methods that populate them through other data contexts.

When I new an Address object, assign it its properties, and try to save it, I get the exception mentioned.  Are you saying I have to detach the AddressType, State and Country objects separately?  

1) This is crazy.

2) I could have multiple key relationships for State (for instance).  Are you saying I have to default every single foreign key?

3) It still doesn't seem to work, I can't save a new address without getting the exception.

# re: Linq to SQL: How to Attach object to a different data context

Saturday, December 08, 2007 6:34 PM by jdn

Also, this error is throw on build:

Cannot implicitly convert type 'System.ComponentModel.PropertyChangingEventHandler' to 'System.ComponentModel.PropertyChangedEventHandler'

on this line:

this.PropertyChanged = this.PropertyChanging = null;

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 09, 2007 1:35 AM by jalam

Omar, it would be better if you could place the souce codes with IDE colors. There are some free tools available on the web. Thanks

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 09, 2007 3:53 AM by omar

I corrected the code. There was a mistake on this line:

this.PropertyChanged = this.PropertyChanging = null;

Each of these need to be individually set to null.

this.PropertyChanged = null;

this.PropertyChanging = null;

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 09, 2007 3:58 AM by omar

Andreas:

Not yet. I am not yet convinced Linq to SQL is good for multitier environment. DataContext holds reference to each and every Linq object it produces in order to track changes via PropertyChanging event. Event handlers are by-directional strong reference. That means both the object and the data context are holding reference to each other all the time. It's scary!

# re: Linq to SQL: How to Attach object to a different data context

Tuesday, December 25, 2007 12:57 AM by cypeopebtew

[url=http://bettyjhurd.fizwig.com/]speed skater[/url]

# re: Linq to SQL: How to Attach object to a different data context

Tuesday, December 25, 2007 12:57 AM by cypeopebtew

[url=http://bettyjhurd.fizwig.com/]speed skater[/url]

# re: Linq to SQL: How to Attach object to a different data context

Friday, December 28, 2007 8:12 AM by home-based businesses

look :

[URL=ps3forums.com/member.php]work home home based business opportunit[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Friday, December 28, 2007 8:12 AM by home-based businesses

look :

[URL=ps3forums.com/member.php]work home home based business opportunit[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 30, 2007 11:23 AM by SyncMicyillup

wery well, guys

[URL=samuelbjolley.googlepages.com/index.html]absintheoil[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 30, 2007 11:24 AM by SyncMicyillup

wery well, guys

[URL=samuelbjolley.googlepages.com/index.html]absintheoil[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 30, 2007 11:24 AM by SyncMicyillup

wery well, guys

[URL=samuelbjolley.googlepages.com/index.html]absintheoil[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Sunday, December 30, 2007 11:25 AM by SyncMicyillup

wery well, guys

[URL=samuelbjolley.googlepages.com/index.html]absintheoil[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Friday, January 04, 2008 1:48 AM by SysfuroSopdof

Hello,

Is everything fine? How are you?

------------------

[url=http://planyourshopping.com]shopping[/url]

# re: Linq to SQL: How to Attach object to a different data context

Saturday, January 05, 2008 9:07 AM by accitaDup

lok it plz

[URL=urengoi.t35.com/discountcallimorphajacobeae1.html]toyindustry[/URL]

# re: Linq to SQL: How to Attach object to a different data context

Sunday, January 06, 2008 5:39 PM by music

very interesting.

i'm adding in RSS Reader

# re: Linq to SQL: How to Attach object to a different data context

Monday, January 07, 2008 4:37 PM by speehycle

lok it plz

<a href=lyssajackelyn.tripod.com/.../a>

# re: Linq to SQL: How to Attach object to a different data context

Monday, January 07, 2008 4:37 PM by speehycle

lok it plz

<a href=lyssajackelyn.tripod.com/.../a>

# re: Linq to SQL: How to Attach object to a different data context

Monday, January 07, 2008 4:37 PM by speehycle

lok it plz

<a href=lyssajackelyn.tripod.com/.../a>

# re: Linq to SQL: How to Attach object to a different data context

Monday, January 07, 2008 4:38 PM by speehycle

lok it plz

<a href=lyssajackelyn.tripod.com/.../a>

# re: Linq to SQL: How to Attach object to a different data context

Monday, January 07, 2008 6:09 PM by empofterypoto

Best <a href=rubyevans.678host.com/jewelry5547.html> jewelry </a> links!

Visit it!

# re: Linq to SQL: How to Attach object to a different data context

Tuesday, January 08, 2008 10:36 AM by ribguasourb

Your site was so interesting and informative I had to call a friend to tell her about it. Great work

Top <a href=ericgraves.12gbfree.com/earring5470.html> earring </a> links!

# re: Linq to SQL: How to Attach object to a different data context

Tuesday, January 15, 2008 2:14 PM by opelprove

Hello all

[url=users4.nofeehost.com/melatonin]melatonin[/url]

Best Regards

# re: Linq to SQL: How to Attach object to a different data context

Wednesday, February 06, 2008 10:37 PM by Rob

Hi Omar,

Just bought your book and it looks ace thanks.

I was wondering if you could elaborate on the LINQ multitier solution you came up with in there.  You're using XMLSerialisation to detach the object, then reform it without any attachments (because the contract was disregarded during the serialisation process).

Is this actually a better way than this post - which I can't get to work either way!  For example, in your book code you've passed an object directly to XMLSerialiser which you need to pass the type instead etc.

Rob

# re: Linq to SQL: How to Attach object to a different data context

Friday, March 07, 2008 5:04 PM by Elad

In one of the comments of the following (excellent) blog:

west-wind.com/.../135659.aspx

A person named Steve provided a solution which works for me (and seems to solve the need for other workarounds such as the detach specified in this blog). Here's his code (note the Refresh):

public void Update(Customer customer)

{

  NorthwindDataContext context = new NorthwindDataContext();

  context.Attach(customer);

  context.Refresh(RefreshMode.KeepCurrentValues, customer);

  context.SubmitChanges();

}

I hope that this really "wraps things up". One thing I have noticed is that once the entity object is reattached to the context, it will eventually rethrow the exception, so basically after "saving" my entity, I refresh it in my cache and this works ok.

# re: Linq to SQL: How to Attach object to a different data context

Wednesday, April 02, 2008 9:10 PM by Emmanuel Buah

Elad, I dont know what your case is but for most people, its the attach that blows up. So you dont even get to define what your RefreshMode is. RefreshMode is also meant for resolving insert, update conflicts. In any case, Omar, you method works except that you have to  detach, attach "before" making the changes that needs to be submitted. Most people were making the changes before detaching and attaching in which case, the context still doesnt know about the changes.

# re: Linq to SQL: How to Attach object to a different data context

Thursday, April 10, 2008 9:54 PM by Steve B

I posted a solution that worked for me after I got this error. Hopefully it can help some other people too.

forums.microsoft.com/.../ShowPost.aspx

# re: Linq to SQL: How to Attach object to a different data context

Monday, May 12, 2008 9:13 AM by Jason

Hi,

could you post the aspx code?

I have a problem with a formview, when I try to send the entity object as a objectdatasource updateparameter, it is passed as empty object.

Thanks in advance,

Jason

# First thoughts on LINQ To SQL

Friday, September 05, 2008 9:06 AM by LA.NET [EN]

In these last couple of days I’ve also been busy looking at LINQ To SQL. By now, I’m able to have some

# re: Linq to SQL: How to Attach object to a different data context

Friday, September 12, 2008 11:03 AM by Thurein

I need to clone Linq objects so can I detach and add the existing ones as new entities?

# re: Linq to SQL: How to Attach object to a different data context

Friday, September 12, 2008 11:10 AM by Thurein

Hi Omar,

   I'm trying to clone linq objects. So can I detach the existing objects and add them as new entities to the same datacontext.

Thanks for your reply.

# re: Linq to SQL: How to Attach object to a different data context

Thursday, September 18, 2008 9:29 AM by Ferenc Mucsi

Hi Omar,

I have spet a lot of time to find the best solution for this trouble:

Before u starting update just simple get the detached employee object.

Employee GetDetachedEmpolee(Employee emp_to_edit)

{

  dataContext db = new dataContext();

  db.DefferesLoadingEnabled = false; //important!!!

 return db.Employees.Where(e=>e.ID == emp_to_edit.ID).SingleOrDefault();

}

# To admin

Tuesday, September 23, 2008 5:30 AM by liffinfip

How i may contact the administrator of a site? I have a question.

# A fantastic site, and brilliant effort.

Tuesday, November 18, 2008 3:58 PM by Vardenafil

The site very professional! Keep up the good work! Oh yes, one extra comment - maybe you could add more pictures too! So, good luck to your team!

Leave a Comment

(required) 
(required) 
(optional)
(required)