none
Infracción de la restricción PRIMARY KEY. No se puede insertar una clave duplicada RRS feed

  • 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 { getset; }

    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
    miércoles, 27 de septiembre de 2017 10:21

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
    lunes, 2 de octubre de 2017 12:47

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).

    miércoles, 27 de septiembre de 2017 15:59
  • 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!!!

    miércoles, 27 de septiembre de 2017 17:34
  • "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


    lunes, 2 de octubre de 2017 7:55
  • 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
    lunes, 2 de octubre de 2017 12:47
  • 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.

    Ok lo probaré. Gracias
    martes, 3 de octubre de 2017 13:45
  • 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

     
    martes, 28 de abril de 2020 20:09