7

Tengo una entidad con una relación de clave externa con una tabla de usuarios de proveedor de membresía asp.net.Entity Framework: ya se ha agregado un elemento con la misma clave. - Error al tratar de definir una relación de clave externa

Esta parte del modelo se parece a esto:

alt text

Me parece que no puede asignar la relación de clave externa cuando se inserta el registro de la tabla usuarios, el registro que contiene la clave externa a la tabla aspnet_Users . Sigo recibiendo el error:

An item with the same key has already been added.

El código que estoy usando el siguiente aspecto:

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(); 

es el tema que estoy pidiendo a la EF para agregar un nuevo registro aspnet_Users mesa (el récord de la tabla de clave primaria asociada) cuando ese registro ya está allí?

¿Cómo puedo asignar un valor de clave externa a una entidad en donde ya existe el registro de clave principal?

Actualizado bloque de código de prueba:

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(); 

Este código genera el error:

An item with the same key has already been added.

+1

es 'membershipUser' rastreados por el (mismo) DataContext? –

+2

Sí, el registro de usuario miembro fue recuperado por la misma instancia de modelo de entidad que se está utilizando para confirmar el nuevo registro de usuario. – BrooklynDev

Respuesta

8

OK pensé éste hacia fuera. Como de costumbre, solo cometí un error al no captarlo de inmediato porque estaba buscando en el lugar equivocado.

El problema era debido a mi herencia de tablas y la configuración a nivel de base de datos. Tenía el campo clave externa de la tabla hija (UserAdmin) definido como una identidad, que luego aparecía en mi modelo como StoreGeneratedPattern = Identity. Esto estaba causando que 'Un elemento con la misma clave ya haya sido agregado error' cuando EF intentaba propagar la clave primaria del padre al campo de clave externa de su hijo.

Una vez me quita la especificación de la identidad de la mesa UserAdmins el tema fue.

Problema resuelto.

2

Sí que es exactamente el problema. ¿Cómo obtuviste la membresía de la entidad usuaria? Si no lo obtuvo de ObjectContext actual, EF cree que es el nuevo e intenta insertarlo en la tabla aspnet_users.

intenta utilizar este código después de añadir el usuario a ObjectSet:

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

Therea son probablemente algunas otras maneras de cómo alcanzar mismo resultado, pero esto funciona para mí.

+1

Intenté usar ChangeObjectState() pero fue en vano, aún obteniendo el error 'Un elemento con la misma clave ya ha sido agregado'. He agregado mi código de prueba se ve en la publicación original. – BrooklynDev

+0

Comprobé tu código y debería funcionar. Además, cuando seleccionas el usuario aspnet por EF, no necesitas establecer su estado, ya está en estado sin cambios. ¿La tabla Usuarios está vacía? ¿La tabla UserId in Users está generada automáticamente?Si usa SQL Server y tiene instalado SQL Profiler, puede verificar qué comandos SQL se ejecutan. –

+0

He ejecutado un perfil en la base de datos y parece que no veo ninguna declaración de inserción después de que el proveedor de Membresía lo tiene para Membership.CreateUser(). Llamar a SaveChanges() no parece ejecutar ninguna instrucción de inserción o actualización en absoluto contra la base de datos. – BrooklynDev

Cuestiones relacionadas