web-dev-qa-db-fra.com

L'instruction de mise à jour, d'insertion ou de suppression de magasin a affecté un nombre inattendu de lignes (0) EntityFramework

L'erreur suivante persiste lorsque j'essaie de sauvegarder les modifications apportées à un contexte: 

L'instruction de mise à jour, d'insertion ou de suppression de magasin a affecté un imprévu nombre de lignes (0). Les entités peuvent avoir été modifiées ou supprimées depuis des entités ont été chargées. Actualisez les entrées ObjectStateManager.

J'ai les cours suivants:

La personne

public class Person : IPerson
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Name
    {
        get
        {
            return FirstName + " " + LastName;
        }
        set{}
    }

    public string Email { get; set; }
    public DateTime? LastModified { get; set; }
    public virtual ICollection<Result> Results { get; set; }
}

Profil de l'utilisateur

public class UserProfile : Person
{
    public UserProfile()
    {
        Faculty = new Faculty();
        Projects = new Collection<Project>();
        Results = new Collection<Result>();
    }
    public string UserName { get; set; }
    public string CNP { get; set; }
    public virtual Faculty Faculty { get; set; }
    public virtual ICollection<Project> Projects { get; set; }
}

Résultat

public abstract class Result:INamedEntity
{
    protected Result()
    {
        ResultType = new ResultType();
    }
    public int Id { get; set; }
    public string Name{get;set;}
    public virtual ResultType ResultType { get; set; }
    public virtual ICollection<Person> People { get; set; }
    public DateTime? LastModified { get; set; }
}

Après avoir ajouté une valeur au contexte en utilisant:

_ctx.Users.Single(u => u.Id == userId).Results.Add(result);

Je reçois l'erreur quand j'appelle _ctx.SaveChanges()

Mise à jour de ma fonction pour:

public bool Save()
{

    try
    {
        _ctx.SaveChanges();
    }
    catch (OptimisticConcurrencyException)
    {
        ((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Users);
        ((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Results);
        _ctx.SaveChanges();
    }
    return true;
}

Mais l'erreur n'est pas interceptée ... Merci

22
trebor

Le problème est que nous sommes deux à travailler sur ce projet, et mon collègue a créé son propre exemple de DBContext, il mettait à jour l'un et l'autre. Donc, pour tous ceux qui ont ce problème dans le futur, assurez-vous de ne pas avoir deux instances différentes de votre DBContext en même temps

13
trebor

Ajoutez ceci à votre edit.cshtml

@Html.HiddenFor(model => model.Id)

J'ai eu ce problème et j'ai constaté que l'ID apparaissait comme 0 car il n'était pas sur la page.

J'ai aussi ceci sur mon ViewModel (j'utilise l'approche du modèle de vue)

[HiddenInput(DisplayValue = false)]
[Key]
public int Id { get; set; }
40
VoltaicShock

Votre exception signifie qu'entre le moment où vous avez récupéré et modifié les données de la base de données, vos données ont été modifiées.

Par défaut, Entity Framework implémente un modèle de concurrence optimiste. Cela signifie que les données de la source de données ne contiennent pas de verrous entre le moment où les données sont interrogées et les données mises à jour. MSDN

comment gérer la concurrence dans un contexte d'objet. MSDN

Ou suivez cette réponse qui actualise le contexte. StackOverflow

2
Suraj Singh

Pour moi, le problème était que je n'avais pas défini correctement les liaisons action:

public ActionResult Edit([Bind(Include = "VehicleID,Name,CreateDate,PowerPS,DrivenKM")] Car car)
    { ... }

VehicleID a été mappé avec le mauvais identifiant. C'est pourquoi Entity Framework a toujours obtenu 0 comme clé primaire.

2
Thomas

Si jamais vous rencontrez ce problème et si aucune des solutions ci-dessus ne vous a aidé, vous pouvez peut-être essayer ceci. J'ai également eu ce problème étrange, et la façon dont j'ai pu le réparer est que j'ai défini le champ a sur clé primaire et l'incrémentation automatique ou la valeur sur identité. Supposons que vous ayez peut-être la table Person et un personID, définissez-la sur clé primaire et assurez-vous qu'elle est incrémentée automatiquement.

1
Clyde

ajoutez la surcharge suivante à ma classe DbContext:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

Appelez ensuite SaveChanges(true) le cas échéant.

1

J'ai aussi rencontré ce message d'erreur. Ce qui a causé mon erreur, ce sont les conflits de clés primaires/étrangères. J'avais introduit de nouvelles données dans ma base de données et mes valeurs de clé étrangère étaient désactivées (erreur dans mon script de téléchargement). 

Utilisez SQL Profiler pour localiser le script d’insertion incriminé. Cela vous aidera probablement à découvrir le problème de la mise à jour.

J'espère que cela aidera quelqu'un d'autre avec des problèmes similaires.

0
Kramerica317

Il existe un conflit, car vous utilisez un verrouillage optimiste. Résolvez les problèmes de simultanéité à l'aide des entrées ObjectStateManager, puis enregistrez à nouveau les modifications. Un exemple de code est disponible dans MSDN site.

0
vijayst

Dans mon cas, j’avais une clé composite et je tentais de mettre à jour une partie de celle-ci (3 colonnes constituent une clé composite sur laquelle j’ai mis à jour uniquement la 3ème colonne), mais EF ne permettait pas de modifier les valeurs de clé pour le même objet. réalisé la mise à jour du dossier par:

Context.Database.ExecuteSqlCommand(udpateCommand);
0
Sadiq

Eh bien, j'ai également été confronté à ce type d'erreur de concurrence tout en travaillant avec Entity Framework 6.13 à l'aide de Code First. Et j'ai aussi lutté pendant des heures avant de le résoudre moi-même. Cela peut donc aider quelqu'un. Une table a été créée avec des clés primaires composites et aujourd'hui, j'ai changé la structure de la table et ne crée qu'une seule clé primaire (avec AutoIncrement) à la place des clés composites et je mets à jour la table par le biais de migrations avec des configurations fluent-api. La table a été mise à jour mais la clé primaire n'a pas été mise à jour avec AutoIncrement et chaque fois que j'essayais d'ajouter un enregistrement, cela montrait l'erreur de simultanéité. Donc, alors que je définissais l'auto-incrémentation du champ et que l'erreur avait disparu. J'espère que ça aide.

0
VID

Je ne sais pas ce qui n'allait pas, mais j'ai juste suivi ces étapes et tout a été résolu. (J'espère que vous pourrez résoudre ce problème comme j'ai pu le faire)
Les étapes sont les suivantes:
(1) Ajoutez le nouveau contrôleur en utilisant un échafaudage sur la base de votre table edmx et du contexte de base de données du fichier EF .
(2) À présent, le problème de la sauvegarde des modifications est la méthode d'édition .
(3) Maintenant, copiez la méthode de montage/le contrôleur entier en échafaudage et collez-le dans votre contrôleur d'origine .
(4) Maintenant, construisez simplement le programme et Voila vous êtes prêt à partir.

Mettre à jour
J'ai découvert que pour que les données puissent être modifiées à partir de la vue, tous les champs doivent être renvoyés pour être écrits à nouveau au contrôleur. Si, au moment de l'édition, l'un des champs de la table des entités est manquant, il ne sera pas possible de le modifier. Surtout si PK est dans Label et envoyé au contrôleur pour édition, il générera cette erreur. 

0
Sorangwala Abbasali

J'ai rencontré cette erreur lors de la création d'un projet, même en essayant de faire une simple insertion.

Nous générions le modèle EF à partir d'une base de données préexistante et la structure définissait automatiquement Entity Key = True sur plusieurs champs.

Régler tout sauf l'ID sur False a résolu le problème.

0
Wildcat Matt

Je suis tombé sur cela quand Google. J'ai eu le même message d'erreur, mais la raison en est que je n'ai pas défini de valeurs obligatoires non nulles.

Peut-être que cette découverte aide quelqu'un.

0
r0m4n

Merci Terry, ajoutons ceci: N'ajoutez pas d'attribut [Obligatoire] à votre clé/ID lors de l'échafaudage . Cela empêche votre contexte d'extraire la clé/id de l'URL .. Cela m'est arrivé dans un contrôleur d'échafaudage après une migration Qui comprenait de nouveaux champs booléens sur le modèle. Ces champs étaient Non définis.

0
Michael D. Parnell

Assurez-vous de transmettre l'ID des deux tables au modèle à partir de la vue. Dans votre cas, c'est la clé de la table Person et UserProfile. Si vous n'avez pas besoin d'afficher l'ID de la page, vous pouvez ajouter @ Html.HiddenFor (model => model.PersonId) et @ Html.HiddenFor (model => model.UserProfileId)

0
IndieTech Solutions