Entity Framework Navigation Property

1

I am trying to run the following code, but this one giving error where it is trying to insert the state back into my bank, however it was fetched through another connection

I know that a solution would be to set the state directly, but I would like to use Navigation only to relate the records, that is, I do not want the State to be saved along with the city. What could you do to resolve this issue?

static void Main(string[] args)
    {
        Estado estado = GetEstado();

        using(TesteContext context = new TesteContext())
        {
            Cidade cidade = new Cidade();                
            cidade.Estado = estado;
            cidade.Descricao = "SM";
            context.Cidade.Add(cidade);
            context.SaveChanges();
        }
    }

    static Estado GetEstado()
    {
        using (TesteContext context = new TesteContext())
        {
            var estado = context.Estado.FirstOrDefault(a => a.EstadoId == 43);

            if (estado == null)
            {
                estado = new Estado();
                estado.EstadoId = 43;
                estado.Descricao = "RS";
                context.Estado.Add(estado);
                context.SaveChanges();
            }

            return estado;
        }
    }

    public class TesteContext: DbContext
    {
        public DbSet<Estado> Estado { get; set; }

        public DbSet<Cidade> Cidade { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer<TesteContext>(new CreateDatabaseIfNotExists<TesteContext>());
            base.OnModelCreating(modelBuilder);
        }
    }

    public class Estado
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
        [Key]
        public int EstadoId { get; set; }

        [MaxLength(100)]
        [Required]
        public string Descricao { get; set; }
    }

    public class Cidade
    {
        [Key]            
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int CidadeId { get; set; }

        [Required]
        public int EstadoId { get; set; }

        [MaxLength(100)]
        [Required]
        public string Descricao { get; set; }

        [ForeignKey("EstadoId")]
        public virtual Estado Estado { get; set; }
    }
    
asked by anonymous 23.10.2014 / 18:08

1 answer

2

Do not do this:

if (estado == null)
{
    estado = new Estado();
    estado.EstadoId = 43; // <--- Evite isso
    estado.Descricao = "RS";
    context.Estado.Add(estado);
    context.SaveChanges();
}

The primary key definition must be made by the Entity Framework, not by you. The correct one is to search as follows for your example:

var estado = context.Estado.FirstOrDefault(a => a.Descricao == "RS");

I'm sure the code will not look like this in the end. It's just a test.

Another thing is about how you use contexts to load information. Doing this:

using (TesteContext context = new TesteContext())
{ ... }

You are deleting the context that loads your information when you return the object. Without an active context, the object is not observed by the Entity Framework and considered a new object.

Controller already has in its Dispose the ability to delete the context at the end of the execution cycle. Therefore, using construction does not need to be used.

Instead, state the context outside of your methods. As you are not a Controller your case, pass the same context used to enter the City also for the search and insertion of the State :

static void Main(string[] args)
{
    var context = new TesteContext();

    var estado = GetEstado(context);

    var cidade = new Cidade();                
    cidade.Estado = estado;
    cidade.Descricao = "SM";
    context.Cidade.Add(cidade);
    context.SaveChanges();
}

static Estado GetEstado(TesteContext context)
{
    var estado = context.Estado.FirstOrDefault(a => a.Descricao == "RS");

    if (estado == null)
    {
        estado = new Estado();
        // estado.EstadoId = 43;
        estado.Descricao = "RS";
        context.Estado.Add(estado);
        context.SaveChanges();
    }

    return estado;
}
    
23.10.2014 / 18:33