If you’ve read parts 1, 2 and indeed 3 you’ll know we’ve covered the CRD of CRUD, today we will cover the ‘U’ – updates! Updates are more complex than the other scenario’s we’ve covered so far, but not unmanageable. Also – in fairness this is a very simple update, more complex updates will require more thought (duh!) but this should be a good starting point. Let’s get to it!
We’ll start on familiar ground – updating the interface, adding an ‘UpdateCar’ method:
[OperationContract]
void UpdateCar(Car car);
and then we’ll need to implement this in the service:
public void UpdateCar(Car car)
{
_db.Cars.Attach(car, true);
_db.SubmitChanges();
}
Now let’s test it to see how it works (remembering to update our service reference in the client!)
CarsServiceClient client = new CarsServiceClient();
Car car = client.GetCar(5);
car.Make = "Fiat";
client.UpdateCar(car);
Fire up the console… ouch! InvalidOperationException!
Let’s try one of the other overloads of the ‘Attach’ method…
public void UpdateCar(Car car)
{
_db.Cars.Attach(car, GetCar(car.ID));
_db.SubmitChanges();
}
Run… fail.. bum. Different exception though, we got a ‘DuplicateKeyException’:
Gah! It appears we can’t attach the object back to the DataContext, so… what about attempting to copy the members?
public void UpdateCar(Car car)
{
Car original = GetCar(car.ID);
original.Make = car.Make;
original.Model = car.Model;
_db.SubmitChanges();
}
Yup, that works, but doesn’t copy the Owner / Previous Owners, to achieve those goals we’d need to do them property by property as well; for example, to do the owner:
public void UpdateCar(Car car)
{
Car original = GetCar(car.ID);
original.Make = car.Make;
original.Model = car.Model;
original.Owner.Surname = car.Owner.Surname;
original.Owner.Title = car.Owner.Title;
_db.SubmitChanges();
}
Messy. Now, this is due to our disconnected manner of working (which we can’t do anything about whilst using WCF), so it’s a coding hit and a pain, as if we add a new property to the car, we need to update our ‘update’ method to deal with it. I guess you could consider going down a reflection route and copying all the properties across. Though – that would still be a pain – checking for ‘EntitySet’ types etc. But that seems complicated.
To be honest, this is the most annoying aspect. I can’t see any way to connect an object that has been created on a client. Maybe someone else knows, hmph, well… That about rounds up the WCF / LINQ CRUD series.. (well, to a point)…
Cheers
Me