J'utilise Entity Framework pour remplir un contrôle de grille. Parfois, lorsque je fais des mises à jour, j'obtiens l'erreur suivante:
L'instruction de mise à jour, d'insertion ou de suppression de magasin a affecté un nombre inattendu de lignes (0). Les entités peuvent avoir été modifiées ou supprimées depuis le chargement des entités. Actualisez les entrées ObjectStateManager.
Je ne peux pas comprendre comment reproduire cela. Mais cela pourrait avoir quelque chose à voir avec la proximité des mises à jour. Quelqu'un a-t-il vu ceci ou quelqu'un sait-il à quoi fait référence le message d'erreur?
Edit: Malheureusement, je ne suis plus en mesure de reproduire le problème que je rencontrais ici, car je me suis éloigné de ce projet et je ne me souviens pas si j'ai finalement trouvé une solution, si un autre développeur l'a corrigée ou si j'y ai travaillé. Je ne peux donc accepter aucune réponse.
la source
Request.Uri
pour voir l'URL réelle de la demande. Dans mon cas, j'avais une logique de suivi qui frappait mon site et chargeait inutilement le contexte de la base de données (et le mettait parfois à jour aussi). Ainsi, la page que je déboguais avait vu ses données écrasées par une logique de code de suivi stupide.Réponses:
C'est un effet secondaire d'une fonctionnalité appelée concurrence optimiste.
Je ne sais pas à 100% comment l'activer / le désactiver dans Entity Framework mais, fondamentalement, ce qu'il vous dit, c'est qu'entre le moment où vous avez récupéré les données de la base de données et le moment où vous avez enregistré vos modifications, quelqu'un d'autre a modifié les données (ce qui signifiait quand vous êtes allé pour l'enregistrer, 0 lignes ont été mises à jour). En termes SQL,
update
lawhere
clause de leur requête contient la valeur d'origine de chaque champ de la ligne, et si 0 ligne est affectée, elle sait que quelque chose s'est mal passé.L'idée derrière cela est que vous ne finirez pas par écraser un changement que votre application ne savait pas s'est produit - c'est essentiellement une petite mesure de sécurité mise en place par .NET sur toutes vos mises à jour.
Si c'est cohérent, il y a des chances que cela se produise dans votre propre logique (EG: vous mettez à jour les données vous-même dans une autre méthode entre la sélection et la mise à jour), mais cela pourrait simplement être une condition de concurrence entre deux applications.
la source
J'ai rencontré cela et cela était dû au fait que le champ ID (clé) de l'entité n'était pas défini. Ainsi, lorsque le contexte est allé enregistrer les données, il n'a pas pu trouver un ID = 0. Assurez-vous de placer un point d'arrêt dans votre instruction de mise à jour et vérifiez que l'ID de l'entité a été défini.
D'après le commentaire de Paul Bellora
la source
Wow, beaucoup de réponses, mais j'ai eu cette erreur quand j'ai fait quelque chose de légèrement différent que personne d'autre n'a mentionné.
Pour faire court, si vous créez un nouvel objet et que vous dites à EF qu'il est modifié à l'aide de
EntityState.Modified
alors il générera cette erreur car il n'existe pas encore dans la base de données. Voici mon code:Oui, cela semble idiot, mais cela est dû au fait que la méthode en question lui avait été
foo
transmise après avoir été créée plus tôt, maintenant elle ne lui estsomeValue
passée que et se créefoo
elle-même.Solution facile, tout changement
EntityState.Modified
deEntityState.Added
ou changer cette ligne entière à:la source
Je faisais face à cette même erreur d'effarouchement ... :) Puis j'ai réalisé que j'oubliais de définir un
@Html.HiddenFor(model => model.UserProfile.UserId)
pour la clé primaire de l'objet en cours de mise à jour! J'ai tendance à oublier ce truc simple mais très important!
Par ailleurs:
HiddenFor
est pour ASP.NET MVC.la source
UserId
sous la forme, très sujet aux pirates informatiques ... cela devrait être rempli par la suite à partir deHttpContext.Current.User.Identity.Name
HiddenFor
vous devrez l'obtenir deHttpContext
toute façon ... Je ne mettrais pas du tout cette propriété sous la forme, ce qui m'obligerait à toujours la remplir côté serveur ...Vérifiez si vous avez oublié l'attribut "DataKeyNames" dans GridView. c'est un must lors de la modification des données dans le GridView
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
la source
Le problème est causé par l'une des deux choses suivantes: -
Concurrency Mode: Fixed
.. et la concurrence optimiste a empêché l'enregistrement des données. C'est à dire. certains ont modifié les données de ligne entre le moment où vous avez reçu les données du serveur et le moment où vous avez enregistré vos données de serveur.StoreGeneratedPattern = Computed
) Et cette ligne n'existe pas.la source
J'ai eu cette même erreur car une partie du PK était une colonne datetime et l'enregistrement inséré utilisait DateTime.Now comme valeur pour cette colonne. Le cadre d'entité insère la valeur avec une précision en millisecondes, puis recherche la valeur qu'il vient d'insérer également avec une précision en millisecondes. Cependant, SqlServer avait arrondi la valeur à la seconde précision, et donc le framework d'entité n'a pas pu trouver la valeur de précision en millisecondes.
La solution consistait à tronquer les millisecondes de DateTime.Now avant l'insertion.
la source
Date
colonne avec uneDateTime
valeurJ'avais le même problème et la réponse de @ webtrifusion a aidé à trouver la solution.
Mon modèle utilisait l'
Bind(Exclude)
attribut sur l'ID de l'entité, ce qui provoquait la valeur de l'ID de l'entité à zéro sur HttpPost.la source
J'ai eu le même problème, je pense que cela a été causé par RowVersion qui était nul. Vérifiez que votre ID et votre RowVersion ne sont pas nuls .
pour plus d'informations, reportez-vous à ce tutoriel
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
la source
J'ai commencé à obtenir cette erreur après être passé du modèle en premier au code en premier. J'ai plusieurs threads mettant à jour une base de données où certains peuvent mettre à jour la même ligne. Je ne sais pas pourquoi je n'ai pas eu de problème en utilisant model-first, supposons qu'il utilise une valeur par défaut de concurrence différente.
Pour le gérer en un seul endroit en connaissant les conditions dans lesquelles il pourrait se produire, j'ai ajouté la surcharge suivante à ma classe DbContext:
Ensuite appelé le
SaveChanges(true)
cas échéant.la source
Vous devez inclure explicitement un BoundField de la clé primaire. Si vous ne voulez pas que l'utilisateur voit la clé primaire, vous devez la cacher via css:
Où «caché» est une classe en CSS dont l'affichage est réglé sur «aucun».
la source
Lors de la modification, incluez l'identifiant ou la clé primaire de l'entité en tant que champ masqué dans la vue
c'est à dire
qui résout le problème.
Aussi, si votre modèle comprend un élément non utilisé, incluez-le également et postez-le sur le contrôleur
la source
J'ai également rencontré cette erreur. Le problème s'est avéré provenir d'un déclencheur sur la table dans laquelle j'essayais d'enregistrer. Le déclencheur a utilisé 'INSTEAD OF INSERT', ce qui signifie qu'aucune ligne n'a été insérée dans cette table, d'où l'erreur. Heureusement, dans le cas où la fonctionnalité de déclenchement était incorrecte, mais je suppose que cela pourrait être une opération valide qui devrait en quelque sorte être gérée dans le code. J'espère que cela aidera quelqu'un un jour.
la source
SELECT SCOPE_IDENTITY() as MyViewId
Je suis tombé sur ce problème sur une table à laquelle il manquait une clé primaire et avait une colonne DATETIME (2, 3) (donc la "clé primaire" de l'entité était une combinaison de toutes les colonnes) ... Lors de l'insertion, l'horodatage avait une heure plus précise (2018-03-20 08: 29: 51.8319154) qui a été tronquée à (2018-03-20 08: 29: 51.832) de sorte que la recherche sur les champs clés échoue.
la source
J'ai également eu cette erreur. Dans certaines situations, l'entité peut ne pas être au courant du contexte de base de données réel que vous utilisez ou le modèle peut être différent. Pour cela, définissez: EntityState.Modified; à EntityState.Added;
Pour faire ça:
Cela garantira que l'entité sait que vous utilisez ou ajoutez l'État avec lequel vous travaillez. À ce stade, toutes les valeurs de modèle correctes doivent être définies. Attention à ne pas perdre les modifications qui pourraient avoir été apportées en arrière-plan.
J'espère que cela t'aides.
la source
Ma version de ligne était nulle, j'ai donc dû l'ajouter à la vue qui a résolu mon problème
la source
La ligne a
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
fait l'affaire dans mon cas:la source
Assurez-vous simplement que la table et le formulaire ont tous deux la clé primaire et edmx mis à jour.
j'ai constaté que les erreurs lors de la mise à jour étaient généralement dues à: - Aucune clé primaire dans le tableau - Aucune clé primaire dans la vue / le formulaire d'édition (par exemple
@Html.HiddenFor(m=>m.Id
)la source
J'ai eu le même problème. Dans mon cas, j'essayais de mettre à jour la clé primaire, ce qui n'est pas autorisé.
la source
J'ai eu cette erreur sporadiquement lors de l'utilisation d'un
async
méthode. Cela ne s'est pas produit depuis que je suis passé à une méthode synchrone.Erreurs sporadiques:
Fonctionne tout le temps:
la source
J'ai eu cette erreur lorsque je supprimais certaines lignes de la base de données (dans la boucle) et ajoutais les nouvelles dans la même table.
Les solutions pour moi étaient de créer dynamiquement un nouveau contexte dans chaque itération de boucle
la source
la source
Cela se produira également si vous essayez de vous insérer dans une situation de contrainte unique, c'est-à-dire si vous ne pouvez avoir qu'un seul type d'adresse par employeur et que vous essayez d'insérer une seconde de ce même type avec le même employeur, vous obtiendrez le même problème .
OU
Cela peut également se produire si toutes les propriétés d'objet qui ont été affectées à, elles ont été affectées avec les mêmes valeurs qu'auparavant.
la source
Si vous essayez de créer un mappage dans votre fichier edmx vers une "fonction Imports", cela peut entraîner cette erreur. Effacez simplement les champs d'insertion, de mise à jour et de suppression qui se trouvent dans les détails de mappage pour une entité donnée dans votre edmx, et cela devrait fonctionner. J'espère que je l'ai dit clairement.
la source
J'ai obtenu cette exception lors de l'attachement d'un objet qui n'existait pas dans la base de données. J'avais supposé que l'objet était chargé à partir d'un contexte distinct, mais si c'était la première fois que l'utilisateur visitait le site, l'objet a été créé à partir de zéro. Nous avons des clés primaires auto-incrémentées, donc je pourrais remplacer
avec
la source
Eh bien, j'ai ce même problème. Mais cela était dû à ma propre erreur. En fait, je sauvegardais un objet au lieu de l'ajouter. C'était donc le conflit.
la source
Une façon de déboguer ce problème dans un environnement Sql Server est d'utiliser le Sql Profiler inclus avec votre copie de SqlServer, ou si vous utilisez la version Express, obtenez gratuitement une copie d'Express Profiler de CodePlex en suivant le lien ci-dessous:
Express Profiler
En utilisant Sql Profiler, vous pouvez accéder à tout ce qui est envoyé par EF à la base de données. Dans mon cas, cela équivalait à:
J'ai copié collé cela dans une fenêtre de requête dans Sql Server et l'ai exécuté. Effectivement, bien qu'elle ait fonctionné, 0 enregistrements ont été affectés par cette requête, d'où l'erreur renvoyée par EF.
Dans mon cas, le problème a été causé par le CategoryID.
Aucun ID de catégorie n'a été identifié par l'ID EF envoyé à la base de données, donc aucun enregistrement n'a été affecté.
Ce n'était pas la faute d'EF mais plutôt un buggy null coalescing "??" dans un contrôleur de vue qui envoyait des non-sens au niveau des données.
la source
Aucune des réponses ci-dessus ne couvrait tout à fait ma situation et la solution.
Code où l'erreur a été lancée dans le contrôleur MVC5:
J'ai reçu cette exception lorsque j'enregistrais un objet dans une vue d'édition. La raison pour laquelle il l'a lancé est que lorsque je suis retourné le sauvegarder, j'avais modifié les propriétés qui formaient la clé primaire de l'objet. Ainsi, définir son état sur Modifié n'avait aucun sens pour EF - c'était une nouvelle entrée, pas une entrée précédemment enregistrée.
Vous pouvez résoudre ce problème en A) modifiant l'appel de sauvegarde pour ajouter l'objet, ou B) ne modifiez simplement pas la clé primaire lors de la modification. J'ai fait B).
la source
Lorsque la réponse acceptée a dit " cela ne finira pas par écraser un changement dont votre application ne savait pas qu'il s'était passé ", j'étais sceptique car mon objet avait été nouvellement créé. Mais il s'avère qu'il y avait une
INSTEAD OF UPDATE, INSERT- TRIGGER
pièce jointe à la table qui mettait à jour une colonne calculée de la même table.Une fois que j'ai changé cela
AFTER INSERT, UPDATE
, cela fonctionnait bien.la source
Cela m'est arrivé en raison d'un décalage entre datetime et datetime2. Étrangement, cela a bien fonctionné avant qu'un testeur ne découvre le problème. Mon modèle Code First incluait un DateTime dans le cadre de la clé primaire:
La colonne générée est une colonne datetime. Lors de l'appel à SaveChanges, EF a généré le SQL suivant:
Puisqu'il essayait de faire correspondre une colonne datetime avec une valeur datetime2, il n'a renvoyé aucun résultat. La seule solution à laquelle je pouvais penser était de changer la colonne en datetime2:
la source
datetime
rapportdatetime2
. Essentiellement, certaines valeurs en millisecondes seront évaluées en correspondance, d'autres non. La même chose m'est arrivée et je suis également passée àDateTime2
.