Principales respuestas
Infracción de la restricción PRIMARY KEY. No se puede insertar una clave duplicada

Pregunta
-
HOla
Tengo un error al insertar clase con EF 6 y MVC 5
Clase:
public partial class appGenericosFamilias { [Key] [Required] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int appGenericoFamiliaId { get; set; }
Código:
appGenericosFamilias _appGenericosFamilias = new appGenericosFamilias();
db.appGenericosFamilias.Add(_appGenericosFamilias);
db.SaveChanges();
Error:
Infracción de la restricción PRIMARY KEY 'PK_GenericosFamilias'. No se puede insertar una clave duplicada en el objeto 'dbo.appGenericosFamilias'.
Se terminó la instrucción.El problema es q ya hay un R con clave 0 pero no debería hacer caso de esa propiedad
He probado todas las opciones de DatabaseGeneratedOption
Alguien sabe?
Gracias
- Editado scascalesp miércoles, 27 de septiembre de 2017 10:22
Respuestas
-
Esta bien como lo tienes:
- Si el campo es Identity en la base de datos, entonces el servidor lo genera automaticamente.
- Al indicer DatabaseGeneratedOption.Identity ya le estas diciendo a EF que la base de datos genera un valor cuando se inserta un registro.
- Al marcarlo como [Key] ya indicas que es la clave primaria (es necesario tenerla, sino EF no funciona).
Asi que si en teoria es correcto y en la practica no esta funcionando, quiere decir que algo no esta bien configurado o no se comporta como creiamos que se estaba comportando. A la vista del error que te sale (se inserta un cero), la impresion que tengo es que el Identity no esta bien configurado en la base de datos (creemos que el campo es identity pero en realidad no lo es). Puedes hacer un par de pruebas para depurarlo: una es insertar a mano un registro desde SSMS sin indicar el valor de ese campo, y ver si realmente lo genera. Otra es activar el Profiler para capturar el trafico SQL y ver que es lo que realmente le esta enviando el cliente al servidor. El conjunto de estas dos pruebas nos permitira aislar el problema y ver si lo que esta fallando es el cliente o el servidor.
- Marcado como respuesta scascalesp martes, 3 de octubre de 2017 13:45
Todas las respuestas
-
¿Por qué dices que "no debería hacer caso de esa propiedad? Lo normal es que sí que haga caso de todas las propiedades salvo que le digas expresamente que no haga caso.
A la clave primaria necesariamente hay que asignarle un valor. Esto puede hacerse bien sea en el lado cliente, o bien en el lado servidor.
Si quieres hacerlo en el lado cliente, tienes que meterle un valor al appGenericoFamiliaId de _appGenericosFamilias antes de llamar al .Add, y ponerle [DatabaseGenerated(DatabaseGeneratedOption.None)] que significa que NO lo desprecie.
Y si quieres hacerlo en el servidor, tienes que decirle al cliente que desprecie ese campo poniendole DatabaseGeneratedOption.Computed o DatabaseGeneratedOption.Identity. Y en este caso, lógicamente, tienes que configurar el servidor de base de datos para que efectivemante haga lo que le acabas de decir al cliente que se hará en el servidor (Computed o Identity). Si le dices al cliente que desprecie el campo, pero en el servidor no generas el valor del campo, se produce el error de clave duplicada (porque vale 0 y ya hay otro 0).
-
Hola:
Desconozco porque un campo que funge como Id no se debe de enviar, pero sugeriria que el campo sea Indentity para que le permitas a la Bd controlar las claves asignadas, de esa forma, ese campo sera ignorado y sera el servidor quien le asigne un valor, no quieres que sea IDENTITY entonces quita el tributo [KEY] y ponselo a otro campo que sepas que nunca se repetira de lo contrario serguiras recibiendo ese error ya que un campo llave no puede contener duplicados.
Saludos desde Monterrey, Nuevo León, México!!!
-
"Si le dices al cliente que desprecie el campo, pero en el servidor no generas el valor del campo, se produce el error de clave duplicada (porque vale 0 y ya hay otro 0)."
En la DB el campo appGenericoFamiliaId es PK y es Identity (se genera solo)
Entiendo que poniendo [DatabaseGenerated(DatabaseGeneratedOption.Identity)] ya le estoy diciendo q a la hora de insertar (que se lo envío como 0 pq. sino tendría q calcularlo con un max antes de insertar) no haga caso del 0 de la propiedad y coga el valor que genera la DB. Pero no me funciona... me devuelve el error
Otra cosa es q tenga q quitarle el Key o el Required pero si se lo quito... como va ha saber porque campo ha de hacer el update? Necesita un [Key] (es decir, primary key) para decir... "a vale, este es el campo PK de la tabla, pues lo busco para hacer el update"
Espero haberme explicado mejor ahora
-
Esta bien como lo tienes:
- Si el campo es Identity en la base de datos, entonces el servidor lo genera automaticamente.
- Al indicer DatabaseGeneratedOption.Identity ya le estas diciendo a EF que la base de datos genera un valor cuando se inserta un registro.
- Al marcarlo como [Key] ya indicas que es la clave primaria (es necesario tenerla, sino EF no funciona).
Asi que si en teoria es correcto y en la practica no esta funcionando, quiere decir que algo no esta bien configurado o no se comporta como creiamos que se estaba comportando. A la vista del error que te sale (se inserta un cero), la impresion que tengo es que el Identity no esta bien configurado en la base de datos (creemos que el campo es identity pero en realidad no lo es). Puedes hacer un par de pruebas para depurarlo: una es insertar a mano un registro desde SSMS sin indicar el valor de ese campo, y ver si realmente lo genera. Otra es activar el Profiler para capturar el trafico SQL y ver que es lo que realmente le esta enviando el cliente al servidor. El conjunto de estas dos pruebas nos permitira aislar el problema y ver si lo que esta fallando es el cliente o el servidor.
- Marcado como respuesta scascalesp martes, 3 de octubre de 2017 13:45
-
Esta bien como lo tienes:
- Si el campo es Identity en la base de datos, entonces el servidor lo genera automaticamente.
- Al indicer DatabaseGeneratedOption.Identity ya le estas diciendo a EF que la base de datos genera un valor cuando se inserta un registro.
- Al marcarlo como [Key] ya indicas que es la clave primaria (es necesario tenerla, sino EF no funciona).
Asi que si en teoria es correcto y en la practica no esta funcionando, quiere decir que algo no esta bien configurado o no se comporta como creiamos que se estaba comportando. A la vista del error que te sale (se inserta un cero), la impresion que tengo es que el Identity no esta bien configurado en la base de datos (creemos que el campo es identity pero en realidad no lo es). Puedes hacer un par de pruebas para depurarlo: una es insertar a mano un registro desde SSMS sin indicar el valor de ese campo, y ver si realmente lo genera. Otra es activar el Profiler para capturar el trafico SQL y ver que es lo que realmente le esta enviando el cliente al servidor. El conjunto de estas dos pruebas nos permitira aislar el problema y ver si lo que esta fallando es el cliente o el servidor.
-
Tenía ese mismo problema. Todo el Código de programación, en ese caso era C#, estaba bueno; en el caso de SQL Server, las tablas relacionadas entre sí estaba mi poblema. Era con las llaves principales en la especificaión de identidad, por lo que debía o tenía que hacer era especificar la identidad en 'Si' y el incremento de identidad a '1' y ya no había
Infracción de la restricción PRIMARY KEY
- Propuesto como respuesta Ramiro Castañeda martes, 28 de abril de 2020 20:09