7

J'ai une entité avec une relation de clé étrangère dans une table d'utilisateurs de fournisseur d'appartenance asp.net.Entity Framework - Un élément avec la même clé a déjà été ajouté. - Erreur lors de la tentative de définition d'une relation de clé étrangère

Cette partie du modèle ressemble à ceci:

alt text

Je ne peux pas sembler affecter la relation de clé étrangère lors de l'insertion du dossier de la table des utilisateurs, le dossier contenant la clé étrangère à la table aspnet_Users . Je continue à obtenir l'erreur:

An item with the same key has already been added.

Le code J'utilise ressemble:

UserAdmin userToAdd = new UserAdmin(); 
... 
userToAdd.aspnet_Users = membershipUser; 
//line above OR line below 
userToAdd.aspnet_UsersReference.EntityKey = new System.Data.EntityKey("ProjectEntities.aspnet_Users", "UserId", membershipUser.UserId); 

db.AddToUsers(userToAdd); 
db.SaveChanges(); 

est la question que je vous pose la EF pour ajouter un nouvel enregistrement de la table aspnet_Users (le record pour la table de clé primaire associée) lorsque cet enregistrement est déjà là?

Comment affecter une valeur de clé étrangère à une entité dans laquelle l'enregistrement de clé primaire existe déjà?

bloc de code de test Mise à jour:

MembershipUser membershipUser = Membership.CreateUser("[email protected]", "pass", "[email protected]"); 

Entities db = new Entities(); 
UserAdmin newUser = new UserAdmin(); 
newUser.Name = "blah"; 
newUser.DateAdded = DateTime.Now; 

Guid key = new Guid(membershipUser.ProviderUserKey.ToString()); 
aspnet_Users membershipUserRecord = db.aspnet_Users.Where(u => u.UserId == key).FirstOrDefault(); 
newUser.aspnet_Users = membershipUserRecord; 
//newUser.aspnet_UsersReference.EntityKey = new System.Data.EntityKey("Entities.aspnet_Users", "UserId", membershipUserRecord.UserId); 
db.ObjectStateManager.ChangeObjectState(membershipUserRecord, EntityState.Unchanged); 

db.AddToUsers(newUser); 
db.SaveChanges(); 

Ce code génère l'erreur:

An item with the same key has already been added.

+1

Est-ce que 'membershipUser' est suivi par le (même) DataContext? –

+2

Oui, l'enregistrement membershipUser a été récupéré par la même instance de modèle d'entité que celle utilisée pour valider le nouvel enregistrement utilisateur. – BrooklynDev

Répondre

8

OK J'ai trouvé celui-ci. Comme d'habitude, c'était juste moi qui faisais une erreur et ne l'attrapais pas tout de suite parce que je regardais au mauvais endroit.

Le problème était dû à l'héritage de ma table et à la configuration au niveau de la base de données. J'ai défini le champ de clé étrangère de la table enfant (UserAdmin) comme une identité, qui est alors apparue dans mon modèle sous le nom StoreGeneratedPattern = Identity. Cela provoquait l'erreur "Un élément avec la même clé a déjà été ajouté" lorsque EF essayait de propager la clé primaire du parent à son champ de clé étrangère.

Une fois que j'ai supprimé la spécification d'identité de la table UserAdmins, le problème a disparu.

Problème résolu.

2

Oui, c'est exactement le problème. Comment avez-vous obtenu l'entité membershipUser? Si vous ne l'avez pas obtenu à partir de l'ObjectContext EF actuel pense qu'il s'agit du nouveau et qu'il essaie de l'insérer dans la table aspnet_users.

Essayez d'utiliser ce code après avoir ajouté l'utilisateur à ObjectSet:

// db is ObjectContext instance 
db.ObjectStateManager.ChangeObjectState(membershipUser, EntityState.Unchanged); 

Therea sont probablement d'autres façons comment obtenir même résultat, mais cela fonctionne pour moi.

+1

J'ai essayé d'utiliser ChangeObjectState() mais en vain, obtenant toujours l'erreur «Un élément avec la même clé a déjà été ajouté». J'ai ajouté mon apparence de code de test dans le message d'origine. – BrooklynDev

+0

J'ai vérifié votre code et cela devrait fonctionner. De plus, lorsque vous sélectionnez l'utilisateur aspnet par EF, vous n'avez pas besoin de définir son état - il est déjà dans l'état inchangé. La table Utilisateurs est-elle vide? UserId dans la table des utilisateurs est-il généré automatiquement?Si vous utilisez SQL Server et si vous avez installé SQL Profiler, vous pouvez vérifier quelles commandes SQL sont exécutées. –

+0

J'ai exécuté un profil sur la base de données et je ne vois aucune instruction d'insertion après que le fournisseur d'appartenance a fait cela pour Membership.CreateUser(). Appeler SaveChanges() ne semble pas du tout exécuter des instructions d'insertion ou de mise à jour dans la base de données. – BrooklynDev