En utilisant LINQ-to-Entities 4.0, existe-t-il un modèle ou une construction correcte pour implémenter en toute sécurité "if not exists then insert"?Implémentation si-non-existe-insertion à l'aide d'Entity Framework sans conditions de concurrence
Par exemple, j'ai actuellement une table qui suit les «favoris de l'utilisateur» - les utilisateurs peuvent ajouter ou supprimer des articles de leur liste de favoris.
La table sous-jacente n'est pas une véritable relation plusieurs-à-plusieurs, mais effectue plutôt le suivi d'informations supplémentaires telles que la date d'ajout du favori. L'insertion de deux favoris avec la même paire Utilisateur/Article entraîne une erreur de clé dupliquée, si nécessaire.
Je suis actuellement mis en œuvre le « if not exists puis insérez » logique dans la couche de données en utilisant C#:
if (!entities.FavoriteArticles.Any(
f => f.UserId == userId &&
f.ArticleId == articleId))
{
FavoriteArticle favorite = new FavoriteArticle();
favorite.UserId = userId;
favorite.ArticleId = articleId;
favorite.DateAdded = DateTime.Now;
Entities.AddToFavoriteArticles(favorite);
Entities.SaveChanges();
}
Le problème avec cette mise en œuvre est qu'il est sensible aux conditions course. Par exemple, si un utilisateur clique deux fois sur le lien "Ajouter aux favoris", deux demandes peuvent être envoyées au serveur. La première demande réussit, tandis que la deuxième demande (celle que l'utilisateur voit) échoue avec une exception UpdateException enveloppant une exception SqlException pour l'erreur de clé en double.
Avec les procédures stockées T-SQL, je peux utiliser des transactions avec des indicateurs de verrouillage pour m'assurer qu'aucune condition de concurrence ne se produit. Existe-t-il une méthode propre pour éviter la condition de concurrence dans Entity Framework sans avoir recours à des procédures stockées ou à des avalement aveugles?
avez-vous regardé 'using (var tran = new TransactionScope())'? – RPM1984