views:

23

answers:

2

Hi

I am a tad befuddled. I can't reason why the following works:

    AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection formValues) {
       Dinner dinner = dinnerRepository.GetDinner(id);
       UpdateModel(dinner);
       dinnerRepository.Save();
       return RedirectToAction("Details", new { id = dinner.DinnerID });
    }

The sample is taken from Scott Guthrie's NerdDinner walkthrough, where dinnerRepository.Save() is defined as:

public void Save() {
   db.SubmitChanges();
}

And dinnerRepository.GetDinner(id) is defined as follows:

public Dinner GetDinner(int id) {
   return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
}

Ie, how does the the db NerdDinnerDataContext "know" to save the dinner object?

There must be a hole in my understanding of Linq To SQL, but blowed if I can pin point it. OK, so the dinner object has an id, but what tells db that there are changes to submit for that specific record with that Id?

I just can't see it. Must be the World Cup...

I can only think that the DataContext object, db, keeps a reference to the dinner object that was got using the GetDinner method call. But... It all feels a bit 'magical'

Andrew

A: 

As you suspect it is handled by the ORM layer (which is either Linq2SQL or entity framework...don't recall which). It is not uncommon for ORM layers to track changes to the objects they are managing, and since the object that has changed was retrieved from the ORM layer (via the db.Dinners.SingleOrDefault() call, the ORM is tracking changes to that object, so it knows that it has changed when you call SubmitChanges. It is all part of the magic of ORMs.

ckramer
Fine, but how does it know which object to use as the updated record that has the changes? Clearly, it keeps a reference to the object that was created. Will look at those properties. Clearly, LINQ To SQL does more than I thought it did. Will have to get to the bottom of this one. Many thanks to both of you. One has to get the biscuit, so will prize Jacob who answered first.
awrigley
I'm not sure of the details of how Linq2Sql does it's work, and you may or may not be able to dig into the code to find out. If you are interested NHibernate also tracks which objects were retrieved from the database, and which were created new, along with all of the changes that occurred to those objects (and it does it using things like Dynamic Proxies). You may find it interesting to review the NHibernate source code and see what their approach to solving that particular problem is.
ckramer
I am looking into it, and yes, a datacontext instance tracks the data it has retrieved whilst it is in scope. This was a big hole in my understanding and I need to fill it in. Just need to figure out exactly how the references work.
awrigley
A: 

You should look at the generated code for the LINQ to SQL classes. You'll see that the property setters and getters for the classes contain change tracking so that the next time the repository is saved, the proper SQL statements are generated to commit any mutations made the the objects.

Jacob