2009-03-26 9 views
3

J'ai récemment lu sur LINQ pour commencer à l'implémenter, et il y a une chose particulière sur la façon dont il génère des requêtes UPDATE qui me dérange.LINQ Conflict Detection: Définition de l'attribut UpdateCheck

Création du code d'entités en utilisant automatiquement SQLMetal ou l'objet Relational Designer, apparemment tous les champs pour toutes les tables auront attribuer UpdateCheck.Always, ce qui signifie que pour chaque UPDATE et DELETE, je vais instruction SQL comme celui-ci :

UPDATE table SET a = 'a' WHERE a='x' AND b='x' ... AND z='x', ad infinitum 

maintenant, appelez-moi un puriste, mais cela me semble extrêmement inefficace, et il se sent comme une mauvaise idée de toute façon, même si ce ne inefficace. Je sais que l'extraction sera effectuée par la clé primaire en cluster, donc ce n'est pas lent, mais SQL doit encore vérifier chaque champ après cela pour s'assurer qu'il correspond.

Certes, dans certains applications très sensibles quelque chose comme cela peut être utile, mais pour l'application Web typique (pensez débordement de la pile), il semble que UpdateCheck.WhenChanged serait un défaut plus approprié, et je personnellement préférez UpdateCheck.Never, puisque LINQ ne mettra à jour que les champs réels qui ont changé, pas tous les champs, et dans la plupart des cas, la deuxième personne éditant quelque chose gagne quand même. Cela signifie que si deux personnes parviennent à modifier le même champ de la même ligne dans le court laps de temps entre la lecture de cette ligne et le lancement de la mise à jour, le conflit qui sera trouvé ne sera pas déclenché. Mais en réalité, c'est un cas très rare. La seule chose que nous voudrions éviter quand deux personnes changent la même chose ne sera pas attrapée par cela, parce qu'elles ne cliqueront pas sur Soumettre exactement au même moment de toute façon, donc il n'y aura pas de conflit au moment du second DataContext lit et met à jour l'enregistrement (à moins que le DataContext soit laissé ouvert et stocké dans la session quand la page est montrée, ou quelque autre idée sérieusement mauvaise comme cela).

Cependant, aussi rare que cela puisse être, j'aimerais vraiment ne pas avoir d'exceptions dans mon code de temps en temps si cela se produit.

Donc, ma première question est: ai-je tort de croire cela? (encore une fois, pour les applications Web "typiques", pas pour les applications bancaires) Ai-je manqué une raison pour laquelle UpdateCheck.Always par défaut est une idée saine?

Ma deuxième question est la suivante: puis-je changer cela de façon civilisée? Existe-t-il un moyen de dire à SQLMetal ou à l'ORD quel attribut UpdateCheck définir? J'essaie d'éviter la situation où je dois me rappeler d'exécuter un outil que je vais devoir faire qui va prendre quelques expressions rationnelles et éditer tous les attributs dans le fichier directement, car il est évident qu'à un certain point nous ' ll exécutera SQLMetal après une mise à jour à la base de données, nous n'exécuterons pas cet outil, et tout notre code se cassera de façon très subtile que nous ne trouverons probablement pas en testant en dev.

Des suggestions?
Les histoires de guerre sont plus que bienvenues, j'aimerais apprendre des expériences des autres à ce sujet.

Merci beaucoup!

Répondre

2

Eh bien, pour répondre à la première question - je suis d'accord avec vous. Je ne suis pas un grand fan de cette concurrence optimiste "intégrée", surtout si vous avez des colonnes d'horodatage ou des champs dont la garantie n'est pas la même après une mise à jour.Pour répondre à la deuxième question - je ne connais aucun moyen de contourner l'approche par défaut de SqlMetal (UpdateCheck = Always), nous avons fini par écrire un outil qui définit UpdateCheck = Never pour les colonnes appropriées. Nous utilisons un fichier batch pour appeler SqlMetal et ensuite exécuter l'outil). Oh, alors que j'y pense - c'était aussi un régal de trouver que SqlMetal modélise aussi les relations pour définir une clé étrangère sur null au lieu de "Supprimer On Null" (pour les tables jointes en particulier). Nous avons dû utiliser le même outil de post-génération pour les définir correctement.

+0

J'ai fait la même chose! – Keltex