problem with update Entity Framework 6

Asked

Viewed 791 times

3

This is my method of updating:

public dynamic Atualizar(TEntity obj)
{
    dynamic data = null;
    using (ClassContexto ctx = new ClassContexto(ClassMaster.conexao()))
    {
        try
        {
            ctx.Entry(obj).State = EntityState.Modified;                    
            ctx.SaveChanges();
            data = "200";
        }
        catch (DbEntityValidationException e)
        {
            data = e.EntityValidationErrors;
        }
        catch (Exception erro)
        {
            try
            {
                data = erro.InnerException.ToString();
                return data;
            }
            catch
            {
                data = erro.Message.ToString();
                return data;
            }
        }
        finally
        {
        }
    }
    return data;
}

I have a Poi class, which has a collection of contacts. To save, I pass an object of type Poi with a collection of contacts. Works just right.

The problem is to update, step the same Poi object (with a collection of contacts) to the above method, but it only changes the Poi table. There’s something wrong with the method ?


This is the test method. See how I populate the objects:

  [TestMethod]
    public void updatePoiContato2()
    {           

        poiModel.t0031_id_poi = 56;
        poiModel.t0030_id_tipo_poi = 2;
       // poiModel.t0030_id_tipo_poi = poiModel.t0030_id_tipo_poi;
        poiModel.t0031_razao = "TESTE UPDATE" + DateTime.Now.ToString();
        poiModel.t0031_fantasia = "TESTE UPDATE" + DateTime.Now.ToString();
        poiModel.t0031_cnpj_cpf = "12.935.236/0001-97";
        poiModel.t0031_ie_rg = "234234324234";
        poiModel.t0031_situacao = 1;
        poiModel.t0031_dt_cadastro = poiModel.t0031_dt_cadastro;
        poiModel.t0031_alldata = poiModel.t0031_razao + poiModel.t0031_fantasia + poiModel.t0031_cnpj_cpf + poiModel.t0031_ie_rg;


        PoiContatoModel model1 = new PoiContatoModel();
        model1.t0031_id_poi = 56;
        model1.t0033_id_contato = 6;
        model1.t0033_nome_contato = "TESTE UPDATE";
        model1.t0033_tipo_enum = "CELULAR";
        model1.t0033_valor_enum = "41-9174-3185";

        PoiContatoModel model2 = new PoiContatoModel();
        model2.t0031_id_poi = 56;
        model2.t0033_id_contato = 7;           
        model2.t0033_nome_contato = "TESTE UPDATE";
        model2.t0033_tipo_enum = "CELULAR";
        model2.t0033_valor_enum = "41-9174-3185";

        ICollection<PoiContatoModel> contatos = new List<PoiContatoModel>();
        contatos.Add(model1);
        contatos.Add(model2);

        poiModel.Contatos = contatos;            

        var result = poiDto.save(poiModel, "100", "a");
        Assert.AreEqual(true, result.Contains("200"));
    }

1 answer

3

In fact it will not work for editing. When you do:

    PoiContatoModel model1 = new PoiContatoModel();
    model1.t0031_id_poi = 56;
    model1.t0033_id_contato = 6;
    model1.t0033_nome_contato = "TESTE UPDATE";
    model1.t0033_tipo_enum = "CELULAR";
    model1.t0033_valor_enum = "41-9174-3185";

    PoiContatoModel model2 = new PoiContatoModel();
    model2.t0031_id_poi = 56;
    model2.t0033_id_contato = 7;           
    model2.t0033_nome_contato = "TESTE UPDATE";
    model2.t0033_tipo_enum = "CELULAR";
    model2.t0033_valor_enum = "41-9174-3185";

    ICollection<PoiContatoModel> contatos = new List<PoiContatoModel>();
    contatos.Add(model1);
    contatos.Add(model2);

    poiModel.Contatos = contatos;

You are recreating your two contacts, not updating existing contacts. As much as the information is the same (even with the mentioned Ids), the Entity Framework does not thus understand to check that the contact lists are not the same.

The correct would be the following:

var poi = contexto.Pois.Include(p => p.Contatos).SingleOrDefault(p => p.t0031_id_poi == 56);
poi.t0030_id_tipo_poi = 2;
// poiModel.t0030_id_tipo_poi = poiModel.t0030_id_tipo_poi;
poi.t0031_razao = "TESTE UPDATE" + DateTime.Now.ToString();
poi.t0031_fantasia = "TESTE UPDATE" + DateTime.Now.ToString();
poi.t0031_cnpj_cpf = "12.935.236/0001-97";
poi.t0031_ie_rg = "234234324234";
poi.t0031_situacao = 1;
poi.t0031_dt_cadastro = poiModel.t0031_dt_cadastro;
poi.t0031_alldata = poiModel.t0031_razao + poiModel.t0031_fantasia + poiModel.t0031_cnpj_cpf + poiModel.t0031_ie_rg;

var contato1 = poi.Contatos.SingleOrDefault(c => c.t0033_id_contato == 6);
contato1.t0033_nome_contato = "TESTE UPDATE";
contato1.t0033_tipo_enum = "CELULAR";
contato1.t0033_valor_enum = "41-9174-3185";

var contato2 = poi.Contatos.SingleOrDefault(c => c.t0033_id_contato == 7);
contato2.t0033_nome_contato = "TESTE UPDATE";
contato2.t0033_tipo_enum = "CELULAR";
contato2.t0033_valor_enum = "41-9174-3185";

var result = poiDto.save(poi, "100", "a");
Assert.AreEqual(true, result.Contains("200"));

In fact, there are a number of bad practices arising from the development of other methodologies, namely:

Properties of Model should not have the same column name as the database

The Entity Framework is agnostic, i.e., it is not assembled to function only on top of a relational database schema. Anything can be a data source (even a well-structured text file, in theory). Still, if you want to change the columns of name, you can do this using Attributes. For example:

[Column("t0033_id_contato")]
public int ContatoId { get; set; }

It is also possible to rename the table into a database.

DTO’s do not persist objects

DTO’s are analogous to Models, with reduced logic. See the definition. The difference between a DTO and a Model is that the Model explains the relations between others Models, the validation conditions of each field and additional properties mounted from data fields.

Possibly what you wanted to use there is a Repository, but I have said a few times here that Entity Framework is already a repository, then this effort makes no sense.

Do not change Id’s in editing a Model in the Entity Framework

To change an object coming from another entity in the Entity Framework, you must not do so by Id. It shall select the object of the foreign entity and assign the object itself. Here I explain the reason. Here I explain in another way.

Browser other questions tagged

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