2010-03-01 7 views
4

Nous utilisons des requêtes générées par Linq pour la récupération de données mais pour INSERT et UPDATE, nous n'autorisons pas le SQL généré, mais nous limitons à l'utilisation des procédures stockées.Linq2SQL utilisant Update StoredProcedure

J'ai connecté le comportement Mise à jour et insertion dans DBML aux procédures stockées. Les procédures sont appelées, les données sont insérées/mises à jour = toutes si elles sont bonnes, sauf dans le cas d'une concurrence optimiste.

Si un enregistrement a été modifié entre la récupération et la mise à jour, la mise à jour doit échouer.

Lorsque LINQ génère l'instruction de mise à jour lui-même, il jette un ChangeConflictException comme prévu, mais en utilisant la procédure stockée pas exception est levée.

Merci beaucoup pour toute aide à ce sujet!

Répondre

3

Lors de la configuration du comportement UPDATE pour utiliser la procédure stockée de mise à jour, Linq2SQL génère une méthode qui ne lance pas d'exceptions de concurrence. Pour gérer l'accès concurrentiel optimiste I found a proposed solution in the MSDN forums

Vous pouvez mettre en œuvre la méthode de mise à jour vous-même dans la classe patial DataContext et jeter un ChangeConflictException.

Pour ce faire, vous devez:

  • écrire une procédure de mise à jour stockée qui prend les valeurs actuelles et originales comme paramètres
    • à l'aide WHERE columnA = OriginalValueA ... mettre à jour que si les valeurs ne sont pas modifiées
    • la dernière ligne dans la procédure stockée est RETURN @@ROWCOUNT
    • le rowcount vous permet de voir si la ligne a été mise à jour ou non
  • dans le DBML définir le comportement de mise à jour de « runtime utilisation »
  • la classe partielle xxxDataContext mettre en œuvre une méthode de mise à jour comme celui-ci:
    • le code est tiré de ce que Linq2SQL génère, juste la dernière ligne Jeté l'exception est ajouté
partial void UpdateYourEntityClass(YourEntityClass obj) 
     { 
      EntityClass original = ((YourEntityClass)(EntityClasss.GetOriginalEntityState(obj))); 
      int result = this.YourEntityClassUpdate((...)); 
      if (result == 0) throw new ChangeConflictException(); 
     } 

Fonctionnement, mais pas direct. D'autres options?

0

Cela ne me surprend pas. Lorsque vous appelez une procédure stockée pour effectuer vos mises à jour et vos suppressions, vous devez effectuer votre propre vérification de concurrence. L2S ne sera pas capable de le faire parce que vous avez essentiellement coupé L2S hors de la boucle en utilisant des procs stockés.

C'est l'une des raisons pour lesquelles nous n'utilisons aucune procédure stockée sans back-end L2S lors d'insertions/mises à jour/suppressions. Un autre inconvénient de l'utilisation des procédures stockées est que vous perdez la vérification de type forte sur vos instructions insert/update/delete.

+0

Merci! Le concepteur DBML permet de mapper le comportement INSERT, UPDATE et DELETE aux procédures stockées. Et il permet également de mapper les valeurs d'origine aux paramètres de la procédure stockée de mise à jour. La seule pièce manquante est la vérification de rowcount et de lancer une exception ChangeConflictException. Tout est là mais le code généré dans Designer.cs ne lève pas l'exception. – PeterFromCologne