La mise à jour en mode optimiste
Le pattern classique de détachement / attachement des entités est le suivant :
Le serveur récupère l'entité.
Le serveur l'envoit au client qui va la cloner.
Pour faire un update, le client va renvoyer au serveur l'entité initiale + l'entité modifiée.
Ensuite, le serveur instancie un nouveau contexte, attache l'entité initiale, appelle la méthode ApplyPropertyChanges avec l'entité modifié et enfin sauvegarde le contexte.
Cependant dans le cas où l'on ne se soucie pas des modifications éventuellement faites entre temps et qu'on considère que le dernier qui écrit a raison pour l'ensemble des propriétés, on peut se passer de l'entité initiale.
Avant de faire le ApplyPropertyChanges, il faut s'assurer que l'entité est bien dans le contexte. Pour cela, il suffit de la récupérer, ce que l'on va faire avec la méthode TryGetObjectByKey. Ensuite, l'appel de ApplyPropertyChanges et SaveChanges suffira à mettre à jour la base.
Cet exemple de code n'est pas un code client / serveur mais permet de valider la solution que je propose.
NorthwindModel.Categories c;
NorthwindModel.Categories c2;
using (var context = new NorthwindModel.NorthwindEntities())
{
context.Categories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
c = context.Categories.First();
}
using (var context = new NorthwindModel.NorthwindEntities())
{
c2 = context.Categories.First();
context.DeleteObject(c2);
context.SaveChanges();
}
using (var context = new NorthwindModel.NorthwindEntities())
{
object o;
context.TryGetObjectByKey(c.EntityKey, out o);
context.ApplyPropertyChanges("Categories", c);
context.SaveChanges();
}
Avec l'attachement puis le ApplyPropertyChanged suivi du SaveChanges ne fait rien si le row a été entre temps supprimé en base.
Avec le code précédent, on aura une exception sur le ApplyPropertyChanges car le TryGetObjectByKey ne chargera rien dans le contexte. Par contre avec le code suivant, non seulement on n'aura plus d'exception mais en plus, le SaveChanges recréera le row en base si celui-ci a été supprimé entre temps.
NorthwindModel.Categories c;
NorthwindModel.Categories c2;
using (var context = new NorthwindModel.NorthwindEntities())
{
context.Categories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
c = context.Categories.First();
}
using (var context = new NorthwindModel.NorthwindEntities())
{
c2 = context.Categories.First();
context.DeleteObject(c2);
context.SaveChanges();
}
using (var context = new NorthwindModel.NorthwindEntities())
{
object o;
context.TryGetObjectByKey(c.EntityKey, out o);
if (o == null)
context.AddToCategories(c);
else
context.ApplyPropertyChanges("Categories", c);
context.SaveChanges();
}
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :