none
Problema con Entity Framework RRS feed

  • Pregunta

  • Buenas tardes tengas todos ustedes, es mi primera pregunta en el foro, espero puedan ayudarme.

    Problema:

    Estoy realizando una aplicación en Windows Forms con Entity Framework, tengo una clase persona y otra ofrenda, la relación es 1 : M (una persona puede tener muchas ofrendas).
    Crear una ofrenda no me presenta gran dificultad, la cosa viene al tratar de editarla.

    Les dejo las entidades, DAO, BL, Cliente:

    Mi entidad OFRENDA:

    public class OFRENDA : BaseEntity
        {
            public int Id { get; set; }
            public int PersonaId { get; set; }
            public System.DateTime Fecha { get; set; }
    
            [Display(Name = "Monto")]
            [Required(ErrorMessage = "Se requiere un monto.")]
            [Range(1.00, 200000000.00, ErrorMessage = "El valor para monto debe ser mayor a 0.")]
            [RegularExpression(@"[\d]{1,4}([.,][\d]{1,2})?", ErrorMessage = "Formato de ingreso: 00.00 ó 00,00")]
            public decimal Monto { get; set; }
            
            [Display(Name = "TipoOfrendaId")]
            [Required(ErrorMessage = "Se requiere un tipo de moneda.")]
            public int TipoOfrendaId { get; set; }
    
            [Display(Name = "TipoMonedaId")]
            [Required(ErrorMessage = "Se requiere un tipo de ofrenda.")]
            public int TipoMonedaId { get; set; }
    
            [Display(Name = "TipoPagoId")]
            [Required(ErrorMessage = "Se requiere un tipo de pago.")]
            public int TipoPagoId { get; set; }
            
            [Display(Name = "Persona")]
            [Required(ErrorMessage = "Se requiere una persona.")]
            public virtual PERSONA PERSONA { get; set; }
            
            //[ForeignKey("TipoMonedaId")]
            [Display(Name = "TipoOfrendaId")]
            [Required(ErrorMessage = "Se requiere un tipo de moneda.")]
            public virtual TIPO_MONEDA TIPO_MONEDA { get; set; }
    
            //[ForeignKey("TipoOfrendaId")]
            [Display(Name = "TipoMonedaId")]
            [Required(ErrorMessage = "Se requiere un tipo de ofrenda.")]
            public virtual TIPO_OFRENDA TIPO_OFRENDA { get; set; }
            
            //[ForeignKey("TipoPagoId")]
            [Display(Name = "TipoPagoId")]
            [Required(ErrorMessage = "Se requiere un tipo de pago.")]
            public virtual TIPO_PAGO TIPO_PAGO { get; set; }
        }


    Mi entidad PERSONA: (tiene más código, solo que lo estoy omitiendo)

    public class PERSONA
        {
            public PERSONA()
            {
                
                this.OFRENDAs = new List<OFRENDA>();
            }
            
            public virtual ICollection<OFRENDA> OFRENDAs { get; set; }
            
            public override string ToString()
            {
                return ApePaterno + " " + ApeMaterno + ", " + Nombres;
            }
    
        }


    Mi interfaz:

    public interface IOfrendaRepository
        {
            OFRENDA GetOfrendaById(Int32 id);
            
            List<OFRENDA> GetFromOfrendasByPersona(string criterio);
    
            void AddOfrenda(OFRENDA ofrenda);
            void UpdateOfrenda(OFRENDA ofrenda);
            void DeleteOfrenda(Int32 id);
        }

    Mi clase Repository (o DAO) que hereda los métodos de la interfaz:

    public void UpdateOfrenda(OFRENDA ofrenda)
            {
                //context.OFRENDAs.Attach(ofrenda);
                context.Entry(ofrenda.PERSONA).State = System.Data.EntityState.Modified;
                context.Entry(ofrenda.TIPO_MONEDA).State = System.Data.EntityState.Modified;
                context.Entry(ofrenda.TIPO_OFRENDA).State = System.Data.EntityState.Modified;
                context.Entry(ofrenda.TIPO_PAGO).State = System.Data.EntityState.Modified;
                context.Entry(ofrenda).State = System.Data.EntityState.Modified;
                context.SaveChanges();
            }


    Mi clase BL (Inyección de dependencias):

    [Dependency]
            public IOfrendaRepository ofrendaRepository { get; set; }
    
    public void UpdateOfrenda(OFRENDA ofrenda)
            {
                var msg = "";
                var ok = ofrenda.Validate(out msg);
                if (ok)
                {
                    ofrendaRepository.UpdateOfrenda(ofrenda);
                }
                else
                {
                    throw new Exception(msg);
                }
            }


    En el frame principal:

    private void BtnGuardar_Click(object sender, EventArgs e)
            {
                var msg = "ERROR";
    
                OFRENDA currentOfrenda = oFRENDABindingSource.Current as OFRENDA;
    
                if (currentOfrenda != null)
                {
                    if (isNew)
                    {
                        try
                        {
                            currentOfrenda.Monto = Convert.ToDecimal(montoTextBox.Text);
                            currentOfrenda.Fecha = fechaDateTimePicker.Value;
                            
                            ofrendaBL.AddOfrenda(currentOfrenda);
                            MessageBox.Show("Registro Correcto", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            Close();
    
                        }
                        catch (Exception ex)
                        {
                            msg = ex.Message;
                            MessageBox.Show(msg, "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                    else
                    {
                        try
                        {
                            currentOfrenda.Monto = Convert.ToDecimal(montoTextBox.Text);
                            currentOfrenda.Fecha = fechaDateTimePicker.Value;
                            ofrendaBL.UpdateOfrenda(currentOfrenda);
                            MessageBox.Show("Modificación Correcta.", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            Close();
    
                        }
                        catch (Exception ex)
                        {
                            msg = ex.Message;
                            MessageBox.Show(msg, "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                }
            }

    Ahora, como ya expliqué, el guardar funciona correctamente, cuando intento modificarlo es donde me genera este error:

    "Se produjo una infracción de una restricción de integridad referencial: los valores de propiedad que definen las restricciones referenciales no son coherentes entre los objetos principal y dependiente de la relación."

    Si le agrego estas líneas de código:

    //currentOfrenda.TIPO_OFRENDA = tipoOBL.GetFromTipoOfrendaById(currentOfrenda.TipoOfrendaId);
    //currentOfrenda.TIPO_PAGO = tipoPBL.GetFromTipoPagoById(currentOfrenda.TipoPagoId);
    //currentOfrenda.TIPO_MONEDA = tipoMBL.GetFromTipoMonedaById(currentOfrenda.TipoMonedaId);
    //currentOfrenda.PERSONA = personaBL.GetFromPersonaById(currentOfrenda.PersonaId);
    El problema se soluciona, pero tengo que hacerlo manualmente, se supone que EF ya se encarga de arreglarlo automáticamente. Quiero encontrar una forma de solucionarlo sin recurrir a la asignación de valor por cada objeto que tenga vinculado, espero alguien pueda ayudarme

    viernes, 13 de diciembre de 2013 20:57

Todas las respuestas

  • hola

    lo primero que recomendaria es que uses fluent para definir el mapping y no atributos

    [Entity Framework][Code First] Asociación uno a muchos (1/3)

    de esta forma podrias definir dos propiedades

    public int PersonaId { get; set; }

    public virtual PERSONA PERSONA { get; set; }

    de esta forma no necesitas asignar la entidad persona cada vez que quieras actualizar la ofrenda, sino con solo definir el id alcanza

    para la relacio usas dos propiedades, la entidad y la propiedad que define el id por eso puse una adicional de nombre PersonaId

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    sábado, 14 de diciembre de 2013 13:06