Entity Framework does not edit FK

-2

I have some difficulties with a large project, and I tried to do a simple replica to post here so that someone can help me. One of the difficulties I'm having and how to edit foreign key fields (FK). I have three entities: Vehicle, Make and Model. As I do not know how foreign key rules work, I do not know how to do it to change that data properly.

The Vehicle entity data I can edit normally, but if I try to change the Tag or Model that was registered I can not, Entity simply does not edit the two fields that make relationships with Brand and Model. I researched here in the forum posts of people who had the same problem, but the solution given to the problems does not apply to mine.

In the example, I'm trying to change the Mark = 3 and Model = 6 from the Id = 3 vehicle, but the Eentity Framework does not update the Mark and Model:

How could you solve the problem to make it work?

Template

Home

classProgram{staticvoidMain(string[]args){Veiculoveiculo=newVeiculo(){VeiculoId=3,Nome="Carro",
                Marca = new MarcaApplication().ListId(2),
                Modelo = new ModeloApplication().ListId(6)
            };

            VeiculoApplication apVeiculo = new VeiculoApplication();
            apVeiculo.EditTB(veiculo);
        }
    }

Domain Layer

public class Veiculo
{
    public int VeiculoId { get; set; }
    public string Nome { get; set; }
    public Modelo Modelo { get; set; }
    public Marca Marca { get; set; }
}

public class Modelo
{
    public int ModeloId { get; set; }
    public string ModeloDescricao { get; set; }
    public virtual IEnumerable<Veiculo> Veiculos { get; set; }
}

public class Marca
{
    public int MarcaId { get; set; }
    public string MarcaDescricao { get; set; }
    public virtual IEnumerable<Veiculo> Veiculos { get; set; }
}

Application Layer

public class VeiculoApplication
{
    public DBContext db { get; set; }

    public VeiculoApplication()
    {
        db = new DBContext();
    }

    public void AddTB(Veiculo tb)
    {
        db.Veiculos.Add(tb);
        db.SaveChanges();
    }

    public void EditTB(Veiculo tb)
    {
        db.Entry(tb).State = EntityState.Modified;
        db.SaveChanges();
    }
    public IEnumerable<Veiculo> ListAll()
    {
        return db.Veiculos.ToList();
    }
}

public class ModeloApplication
{
    public DBContext db { get; set; }

    public ModeloApplication()
    {
        db = new DBContext();
    }

    public Modelo ListId(int id)
    {
        return db.Modelos.Where(m => m.ModeloId == id).First();
    }

    public IEnumerable<Modelo> ListAll()
    {
        return db.Modelos.ToList();
    }
}

public class MarcaApplication
{
    public DBContext db { get; set; }

    public MarcaApplication()
    {
        db = new DBContext();
    }

    public void AddTB(Marca tb)
    {
        db.Marcas.Add(tb);
        db.SaveChanges();
    }

    public Marca ListId(int id)
    {
        return db.Marcas.Where(m => m.MarcaId == id).First();
    }

    public IEnumerable<Marca> ListAll()
    {
        return db.Marcas.ToList();
    }
}

Altered Vehicle Class

public class Veiculo
{
    public int VeiculoId { get; set; }
    public string Nome { get; set; }        
    public int ModeloId { get; set; }
    [ForeignKey("ModeloId")]
    [Column(Order = 1)]
    public Modelo Modelo { get; set; }

    public int MarcaId { get; set; }
    [ForeignKey("MarcaId")]
    [Column(Order = 2)]
    public Marca Marca { get; set; }
}
    
asked by anonymous 19.11.2015 / 20:48

1 answer

7

It will not work because you are misusing the Entity Framework.

In this sentence:

Veiculo veiculo = new Veiculo()
{
    VeiculoId = 3,
    Nome = "Carro",
    Marca = new MarcaApplication().ListId(2),
    Modelo = new ModeloApplication().ListId(6)
};

You are bringing two classes from two different contexts, and using a third context to trigger the update:

public void EditTB(Veiculo tb)
{
    db.Entry(tb).State = EntityState.Modified;
    db.SaveChanges();
}

The example architecture is totally incorrect . I do not know who suggested this to you, but systems made in Entity Framework should not be encapsulated in "applications," precisely because the context has to look at all three entities, vehicle, model, and brand involved in the upgrade.

By separating, you create three contexts that do not communicate with each other, and that may possibly trigger an error when you check the EntityState of the object within the context.

So, the correct way to work is as follows:

class Program
{
    static void Main(string[] args)
    {
        using (DBContext db = new DBContext()) 
        {
            Veiculo veiculo = new Veiculo()
            {
                VeiculoId = 3,
                Nome = "Carro",
                Marca = db.Marcas.FirstOrDefault(m => m.MarcaId == 2),
                Modelo = db.Modelos.FirstOrDefault(m => m.ModeloId == 6)
            };

            db.Entry(veiculo).State = EntityState.Modified;
            db.SaveChanges();
        }
    }
}
    
19.11.2015 / 22:20