4

For my LINQ object Foo, I want to have a "before-and-after" state bracketing my object mutation (coming from an ASP.NET MVC UpdateModel() call as it happens). My idea was to copy the pre-mutation properties from the attached instance into a new unattached instance. Then I'd be able to make the updates in the attached instance and compare their values versus those in the unattached instance. Like so:

Foo real = context.Foos.First(aFoo => aFoo.ID == id)
Foo old = new Foo();
old.Bar = real.Bar;
old.Baz = real.Baz;
SomeSortOfUpdate(real);
if ( !real.Bar.Equals(old.Bar) || real.Baz.Equals(old.Baz) ) {
   LogChanges(old, real);
}
context.SubmitChanges();

Here's the problem: the object referenced by "Foo old" is getting saved (inserted) during context.SubmitChanges(). I traced this back to the assignment of properties that were LINQ-to-SQL associations.

So, for example, if Baz was a table-backed L2S-generated type, including old.Baz = real.Baz would cause a SQL insert for old in addition to any SQL update for real. Removing it (yet keeping old.Bar) makes things work as I expect.

I'm guessing that this is because the Foo.Baz assignment makes a link between Foo and Baz in the saveable object graph. Since real is getting saved, LINQ also walks all of the associated objects and looks for changes. real.Baz isn't itself changed, but it has a new association to old, which isn't yet saved and so gets caught up in the SubmitChanges call.

Is there any way I can prevent objects in the graph from being saved?

2 Answers 2

2

Your analysis is correct. Your assignments are establishing links.

You can modify the generated code to not do this (or write your own). But this means you have to live without auto-generated entity classes. I personally consider this to be unacceptable.

Why don't you serialize the pre-image object into a dictionary? Or copy its property values into a custom DTO class?

From your code I can tell that you want the old values to do change logging. You can do that using

DataContext.GetTable<T>().GetModifiedMembers(entity)
Sign up to request clarification or add additional context in comments.

Comments

-1

I wonder what this would do

 var old = (Foo)real;

I'm wondering if the instance itself is creating the connection

1 Comment

No, that just makes another reference to the same instance. It would not serve my purposes for determining the differences between the old and new states.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.