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.