none
Mensaje de la excepción interna: AcceptChanges no puede continuar porque los valores de clave del objeto están en conflicto con otro objeto en ObjectStateManager. Asegúrese de que los valores de clave son únicos antes de llamar a AcceptChanges. RRS feed

  • Pregunta

  • Hola. Tengo la siguiente función y me da una excepción a la hora de hacer el savechanges.

    Para que os hagáis una idea es el típico ejemplo de Alumno y Asignaturas. Cada alumno puede tener n asignaturas. Yo juego con propuestas y líneas de detalle de propuestas. Es decir, cada propuesta puede tener n líneas de detalle.

    El caso es que en bbdd se guardan bien los datos, pero me aparece ese mensaje. Tengo dos entidades (Propuestas) y (Detalle propuestas). Los "detalles propuestas" van relacionados con las "propuestas".

    Todo se da de alta en la misma pantalla cuando se pulsa el botón guardar. Por lo tanto primero tengo que "crear" la propuesta para después asignarle el "idpropuesta" a cada línea de detalle de "detalles propuestas".

    *Es curioso que si al dar de alta la propuesta y sus líneas de detalle solo creo una línea de detalle no me muestra la excepción, sin embargo si creo mas de una línea de detalle sí lo muestra.

    El mensaje de excepción que me da es el siguiente:

    "Se confirmaron correctamente los cambios en la base de datos, pero se produjo un error al actualizar el contexto del objeto. ObjectContext podría tener un estado incoherente. Mensaje de la excepción interna: AcceptChanges no puede continuar porque los valores de clave del objeto están en conflicto con otro objeto en ObjectStateManager. Asegúrese de que los valores de clave son únicos antes de llamar a AcceptChanges."

    Saludos y a ver si alguien me puede ayudar a resolver el misterio :)

    Gracias

    public static int AddPropuestas(IEnumerable<PPA_Propuestas> ienPropuestas)
            {
                ConexionBDEntities oContexto = GetContexto();

                foreach (PPA_Propuestas oPropuestaNuevo in ienPropuestas)
                {
                        oContexto.PPA_Propuestas.AddObject(oPropuestaNuevo);

                        //1. Con el IdPropuesta Nuevo se lo asignamos a las líneas de detalle y las creamos
                        foreach (PPA_Detalle_Propuesta oDetallePropuesta in oPropuestaNuevo.ienDetallePropuesta)
                        {
                            oDetallePropuesta.idPropuesta = oPropuestaNuevo.idPropuesta;
                            oContexto.PPA_Detalle_Propuesta.AddObject(oDetallePropuesta);
                        }
                }
                
                try
                {
                    //2. Aquí se guarda la propuesta y sus líneas de detalle
                    oContexto.SaveChanges();
                }
                catch (Exception e)
                {
                    RespuestaProcedimientoBaseDeDatosException err = new RespuestaProcedimientoBaseDeDatosException(GetExceptionRespuestaProcedimiento(e));
                    Utiles.Log.AddLog(err);
                    throw err;
                }
                return ienPropuestas.Count();
            }



    jueves, 13 de noviembre de 2014 8:52

Todas las respuestas

  • hola

    porque usas esta linea

    oDetallePropuesta.idPropuesta = oPropuestaNuevo.idPropuesta;

    se supone que si estas insertando el id del detalle es secuencial y lo genera la base de datos, no deberias definir ningun id

    o si lo generas desde codigo valida que es secuencial y no se repite con ningun otro registro, si asignas dod detalles con el mismo id tendras un problema al insertar

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    jueves, 13 de noviembre de 2014 15:26
  • Hola

    Lo tengo puesto así puesto que el entity framework me genera el idpropuesta, por lo tanto a la hora de hacer el ocontexto.SaveChanges(), automáticamente asigna ese idpropuesta nuevo a cada línea de detalle.

    viernes, 14 de noviembre de 2014 8:22
  • Hola,

    Como dice Leandro, el problema esta en esa linea, en el que asignas el Id del objeto, si quieres insertar la entidad como una entidad nueva, debes hacer un Clone de tu objecto, para que EF, no lo identifique como un objeto nuevo, en otro caso (una vez que un objeto tiene un Id) este no puede ser modificado.

    Debes hacer algo asi:

                        foreach (PPA_Detalle_Propuesta oDetallePropuesta in oPropuestaNuevo.ienDetallePropuesta)
                        {

                         if(  oDetallePropuesta.idPropuesta == 0)

                          {
                               oDetallePropuesta.idPropuesta = oPropuestaNuevo.idPropuesta;
                               oContexto.PPA_Detalle_Propuesta.AddObject(oDetallePropuesta);

                           }

                           else

                           {

                                  var newDetalleRespuesta = new T()

                                 //Clone del objeto origen a newDetalleRespuesta, excepto la propiedad Id

                                 oContexto.PPA_Detalle_Propuesta.AddObject(newDetalleRespuesta);

                             }
                        }

    domingo, 16 de noviembre de 2014 21:57
  • Hola.

    Lo he intentado tal y como me has dicho, pero al clonar el objeto menos la propiedad id me da un error al hacer el savechanges.

    Me dice que hay un problema con la foreign key.

    De momento y como ñapa lo he dejado como lo tenía y he intentado controlar la excepción dejando que siga el flujo normal, puesto que los datos en la bbdd los guarda bien.

    martes, 18 de noviembre de 2014 9:49
  • Seguramente tu objeto tenga alguna relacion con otro objecto, en ese caso, ambos tienen que ser Clonados (todas las entidades relacionadas con tu objeto, suponiendo que tu objeto sea el objeto Root).

    Supongo que tienes una relacion one to one, o one to many, y al inserter el Nuevo registro esta constraint es violada, ya que el objeto 'hijo' ya esta relacionado con la version precedente.

    • Propuesto como respuesta Sergio Villén martes, 25 de noviembre de 2014 18:04
    martes, 18 de noviembre de 2014 12:27