Entity Framework does not edit FK

Asked

Viewed 234 times

-2

I’m having some difficulties with a big project, and I tried to make a very simple replica to post here so that someone can help me. One of the difficulties I’m having is how to edit the fields with foreign key (FK). I have three entities: Vehicle, Brand and Model. As I don’t know how foreign key rules work, I don’t know how to change this data properly.

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

In the example, I am trying to change the Brand=3 and Model=6 of the Id=3 vehicle, but the Eentity Framework does not update the Brand and Model:

How could I solve the problem to make it work?

Model

inserir a descrição da imagem aqui

Leading

  class Program
    {
        static void Main(string[] args)
        {
            Veiculo veiculo = new Veiculo()
            {
                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();
    }
}

Class Modified Vehicle

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; }
}
  • 1

    With the Entity Framework it is perfectly possible to work in layers, the way the "Gypsy" is guiding to do is a primitive way of working that goes against MVC standards. I didn’t see the application of layers in the example, I suggest you read some articles on the subject in Wild IT and Macoratti. http://www.tiselvagem.com.br/ http://www.macoratti.net/cshp_3c1.htm http://www.macoratti.net/14/05/aspn_3cam.htm

  • Yes, I saw some related issues in the examples you posted and helped a lot. The Wild IT example is very similar to mine. Thank you!

  • You checked the bank restrictions?

  • Yes Ivan, I did this check, the bank is generated via code. I looked in other forums where there were people with the same problem, but the solutions were diverse, but all the examples I found were developed in layers of different types. William gave me an article that follows the same layering model as mine and I’m trying to keep up with the model. You’ve had similar problems?

1 answer

7

It won’t 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 architecture of the example is totally incorrect. I don’t know who suggested this to you, but systems made in Entity Framework should not be encapsulated in "applications", precisely because the context has to observe all three entities, vehicle, model and brand, involved in the update.

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

Therefore, 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();
        }
    }
}
  • I saw this model in articles and some similar to videos of Academy Live, never gave this problem, including I came to post projects here using this pattern, isolating the context of other classes passing only the model class. I was able to solve the problem by determining the foreign keys, but by including the Mark, I’m having another mistake. A referential Integrity Constraint Violation occurred: The Property value(s) of 'Marca.Marcaid' on one end of a Relationship do not match the Property value(s) of 'Veiculo.Marcaid' on the other end. I will edit my question with the modifications.

  • 5

    I don’t know what articles you’re talking about, but if there are any of these here, they’re all wrong. About this error, it means that you are using a foreign key that does not exist in the original table, in case, Marca.

Browser other questions tagged

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