1

J'utilise des tables Sql sans rowversion ou timestamp. Cependant, j'ai besoin d'utiliser Linq pour mettre à jour certaines valeurs dans la table. Depuis Linq ne peut pas savoir quelles valeurs à mettre à jour, je me sers d'une seconde DataContext pour récupérer l'objet en cours de base de données et utiliser à la fois la base de données et l'objet réel d'entrée pour la méthode Attach comme ceci:Utilisation de Linq SubmitChanges sans TimeStamp et StoredProcedures

Public Sub SaveCustomer(ByVal cust As Customer) 
    Using dc As New AppDataContext() 
     If (cust.Id > 0) Then 
      Dim tempCust As Customer = Nothing 

      Using dc2 As New AppDataContext() 
       tempCust = dc2.Customers.Single(Function(c) c.Id = cust.Id) 
      End Using 

      dc.Customers.Attach(cust, tempCust) 
     Else 
      dc.Customers.InsertOnSubmit(cust) 
     End If 

     dc.SubmitChanges() 
    End Using 
End Sub 

Bien que cela ne Cependant, j'ai un problème: j'utilise aussi StoredProcedures pour mettre à jour certains champs du Client à certains moments. Maintenant, imaginez le flux de travail suivant:

  1. Obtenir client de base de données
  2. Définir un champ client à une nouvelle valeur
  3. Utilisez une procédure stockée pour mettre à jour un autre champ client
  4. Appel SaveCustomer

Ce qui se passe maintenant, c'est que la méthode SaveCustomer récupère l'objet courant de la base de données qui ne contient pas la valeur définie dans le code, mais qui contient la valeur définie par la procédure stockée. En attachant ceci à l'objet réel puis en le soumettant, il mettra à jour la valeur définie dans le code également dans la base de données et ... tadaaaa ... mettra l'autre à NULL, puisque l'objet réel ne contient pas la modification faite par le procédure stockée.

Est-ce que c'était compréhensible?

Existe-t-il une meilleure pratique pour résoudre ce problème?

Répondre

0

Si vous apportez des modifications à l'arrière de l'ORM et n'utilisez pas la vérification de la concurrence, vous aurez des problèmes. Vous ne montrez pas ce que vous avez fait à l'étape "3", mais vous devriez mettre à jour le modèle d'objet pour refléter ces changements, en utilisant peut-être OUTPUT paramètres TSQL. Ou; s'en tenir à l'objet.

Bien sûr, faire quoi que ce soit sans vérification de concurence est une bonne façon de perdre des données - donc mon option préférée est simplement « ajouter un rowversion ». Sinon, vous pourriez peut-être lire l'objet mis à jour et fusionner les choses ... en quelque sorte deviner quelles sont les bonnes données ...

+0

Cela semble raisonnable raisonnable. Cependant, je travaille contre la base de données et l'infrastructure d'un client et il n'introduira pas rowversionioning en raison du fait que la plupart des parties de sa base de données sont générées dynamiquement et qu'il utilise son propre framework pour y accéder. Cependant, je saisis l'opportunité de travailler avec Linq par rapport aux seules tables qui sont statiques pour montrer ce qu'est Linq. ;-) Maintenant, j'ai le problème dû aux SP. Avez-vous une bonne source où je peux apprendre sur la vérification de la concurrence dans ce contexte? – Mephisztoe

0

Si vous voulez déconnecter votre objet d'un contexte et en utiliser un autre pour la mise à jour, vous devez conserver l'objet d'origine, utiliser une version de ligne ou implémenter une sorte de routine de hachage dans votre base de données et conserver le hachage dans le cadre de votre objet. Parmi ceux-ci, je recommande fortement l'option Rowversion. L'utilisation de la valeur actuelle comme valeur d'origine, comme vous essayez de le faire, ne demande que des problèmes de concurrence.

+0

Le problème est - comme indiqué ci-dessus - je ne peux pas ajouter rowversioning, puisque je travaille contre une base de données de clients et il n'y a simplement aucune option pour le modifier. :( – Mephisztoe

Questions connexes