Question

http://geekswithblogs.net/michelotti/archive/2007 /12/17/117791.aspx

J'utilise ASP.NET avec C # et j'essaie d'utiliser linq to SQL pour mettre à jour un contexte de données présenté sur le blog lié ci-dessus. J'ai créé le champ d'horodatage dans la table comme indiqué et j'utilise la méthode suivante:

private void updateRecord(TableName updatedRecord)
{
 context db = new context();
 db.TableName.Attach(updatedRecord,true);
 db.SubmitChanges();
}

Ma question est la suivante: êtes-vous censé attribuer le champ timeStamp à quelque chose de votre updatedRecord avant d'essayer d'appeler la méthode Attach sur votre contexte de données?

Lorsque j'exécute ce code, l'exception suivante est générée: System.Data.Linq.ChangeConflictException: ligne introuvable ou modifiée. Je mets à jour tous les champs, y compris la clé primaire de l'enregistrement que je mets à jour avant de transmettre l'objet à cette méthode de mise à jour. Pendant le débogage, l'attribut TimeStamp de l'objet est null. Je ne sais pas si c'est censé être comme ça ou pas.

Tous mes livres et ressources indiquent que c’est le moyen de le faire, mais aucun d’entre eux n’entre dans les détails de cet attribut TimeStamp.

Je sais que c'est rapide et facile, alors si quelqu'un le sait, faites-le moi savoir.

Était-ce utile?

La solution

Si vous avez une colonne timestamp, alors pour mettre à jour un enregistrement (à partir d'un objet vanilla): oui, je m'attendrais à devoir l'assigner. Sinon, vous perdez la possibilité d'utiliser l'horodatage pour la vérification optimiste de la concurrence.

L'idée est que vous prenez une copie de l'horodatage lorsque vous avez la main sur votre objet (déconnecté), puis lorsque vous mettez à jour, vous pouvez utiliser cette colonne pour vérifier que personne d'autre n'a modifié la ligne.

Il existe deux scénarios courants:

1: si vous n'effectuez qu'une opération de courte durée, commencez par extraire l'enregistrement de la base de données - apportez vos modifications à l'objet, puis simplement SumbitChanges () [toutes avec le même contexte de données]. Le contexte de données gérera la concurrence pour vous.

2: si vous déconnectez l'objet (par exemple, en le transmettant à une application cliente pendant un moment), utilisez quelque chose comme la sérialisation (les objets LINQ-to-SQL prennent en charge DataContractSerializer (vous devez l'activer en option)). Donc, sérialisez l'objet sur le serveur, transmettez-le au client - le client modifie sa copie et la renvoie. Le serveur le désérialise et utilise Attach () et SubmitChanges (). L’enregistrement en mémoire doit toujours avoir l’horodatage qu’il avait lorsqu’il a été extrait de la base de données, afin que nous puissions effectuer une concurrence simultanée optimiste tout au long du processus de déconnexion de l’enregistrement.

Autres conseils

Puisque vous dites que vous avez créé le champ d'horodatage dans la table, je me demande si, dans le cas où cette colonne a été ajoutée ultérieurement, les propriétés de la colonne ne sont peut-être pas définies correctement. Vous souhaiterez peut-être vérifier les propriétés de votre colonne TimeStamp dans le concepteur DBML. Assurez-vous que:

AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never

Le type de données du serveur doit être rowversion NOT NULL

Si elle n'est pas définie pour être générée et synchronisée automatiquement, la version de la ligne ne sera pas renvoyée par l'insertion, car vous ne l'avez pas modifiée lors de l'insertion. Même si cette valeur est générée par la base de données, le DataContext doit le savoir pour pouvoir le gérer correctement.

De plus, maintenant que vous avez une colonne d'horodatage, UpdateCheck doit être défini sur Jamais pour toutes les autres colonnes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top