Why is the Entity Framework generating a new record in the database?

Asked

Viewed 579 times

0

Next, I’m working on a new project , and I have 3 classes.

public class Anuncio
{
    public int AnuncioID { get; set; }

    public string UsuarioID { get; set; }

    [Required]
    [MaxLength(255)]
    [Display(Name="Título")]
    public string Titulo { get; set; }

    [Required]
    [MaxLength(2000)]
    [Display(Name="Descrição")]
    public string Descricao { get; set; }

    [Display(Name="Data do anúncio")]
    public DateTime DataAnunciado { get; set; }

    public Contato Contato { get; set; }

    [Display(Name="Endereço")]
    public Endereco Endereco { get; set; }

    public TipoCategoria Categoria { get; set; }

    public ICollection<Imagem> Imagens { get; set; }

}

public class Endereco
{
    [Key]
    public int EnderecoID { get; set; }

    [Required]
    public Estado Estado { get; set; }

    [Required,Display(Name="Município")]
    public Municipio Municipio { get; set; }

    public string Bairro { get; set; }

    public string Rua { get; set; }

    [Display(Name="Número")]
    public string Numero { get; set; }

    public string Cep { get; set; }
    public string Complemento { get; set; }
}

public class Estado
{
    [Key]
    public int EstadoID { get; set; }
    public string Nome { get; set; }
    public string Sigla { get; set; }
}

So, as you may notice, Anuncio has 1 Endereco, which in turn has 1 Estado.

After I run the application, I include the states, so for example, I have a Estado with EstadoID = 1, Nome = Paraná, Sigla = PR.

When I’m gonna register a new one Anuncio, even defining the instance of Estado on the bench at Anuncio, for example:

public ActionResult NovoAnuncio(Anuncio anuncio)
{        
    if (ModelState.IsValid)
    {             
        Estado estado = db.Estado.Find(1);
        anuncio.Endereco.Estado = estado;

        db.Anuncio.Add(anuncio);
        db.SaveChanges();

        return RedirectToAction("Index", "Home");     
    }

    return View(anuncio);
}

It CREATES another record in the BD.

inserir a descrição da imagem aqui

Why he does not reference the State already registered in the comic?

  • 1

    The "Endereco" object is being populated from where? from what I see the method only receives "Anuncio", you need an instance of "Endereco" to popular power the attribute "Estado".

  • Check how the Address instance is in the Ad, if you are not inserting a new one either.

  • So gentlemen, this Address, is always a new one, the user registers the address in the View, then comes an Announcement object, already with instantiated and populated Address, I only know the state to enter it.

1 answer

2


As I replied on this other issue you are loading the record twice in context and the Entity Framework understands that it is two different records. In your case, this applies to Endereco which does not have a correct reference to Estado.

Modify the following to avoid this:

var estado = db.Estado.Find(1);
anuncio.Endereco.EstadoId = estado.EstadoId;

EDIT

According to comments, two properties are missing for the Entity Framework to work correctly:

Models Endereco.Cs

public class Endereco
{
    ...
    public int EstadoID { get; set; }
    ...
}

Models Anuncio.Cs

public class Anuncio
{
    ...
    public int EnderecoID { get; set; }
    ...
}
  • opa, but my Address does not have an attribute "Estadoid", who has this attribute is my object State, my Address only has attribute State, as it is then?

  • 1

    You need to insert the property concerning the Id of Estado in the Endereco so that the Entity Framework does not get lost while handling its object. Possibly having this column your question code works normally.

  • but then it ends with several principles of object-oriented programming, I will continue looking for a solution, if I do not find I will be obliged to do this =/

  • 2

    Not at all. That’s how the Entity Framework works, including all the examples of the ASP.NET MVC tutorials work this way. Feel free to seek an alternative solution.

  • 2

    @Ukyron If you are not including a property that accesses Foreign key in your class you are only missing the opportunity to access it directly, because internally EF creates FK. Even if you had the property you wouldn’t even need to fetch the Estado as @Ciganomorrisonmendez demonstrated instead of giving Find(1), since it has the PK could simply set anuncio.Endereco.EstadoId = 1; saving a query in DB.

  • well, there’s no way to be purist, so what I researched has to be so for these cases, I will have to put the attribute in the object, I will give the correct answer, just edit the answer, requesting that I put the attribute Estadoid in Address, and Coiendered in Advertising.

  • @Ok ukyron, edited. Thank you!

  • @Ukyron, like you, also disagreed with the weak solution that EF uses to correctly link their FK in EF. This behavior that Voce and I expected to associate the existing class at the base occurs naturally in Nhibernate. At first the ORM should do all that, but some fail to do whole the work...

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.