Match contents of two objects

0

I use the following method to update a given table:

public int alteraBem(tb_bens itemBem)
{
    try
    {
        using (GestaoAtivoEntities db = new GestaoAtivoEntities())
        {
            var bem = db.tb_bens.Where(v => v.int_id_bem.Equals(itemBem.int_id_bem)).FirstOrDefault();

            bem.txt_tag_rfid = itemBem.txt_tag_rfid;
            bem.txt_codigo = itemBem.txt_codigo;
            bem.txt_descricao = itemBem.txt_descricao;
            bem.txt_modelo = itemBem.txt_modelo;
            bem.int_id_local = itemBem.int_id_local;
            bem.int_id_obra = itemBem.int_id_obra;
            bem.int_id_proprietario = itemBem.int_id_proprietario;

            ..... aqui vão os campos restantes......


            db.SaveChanges();

Would you like to create a method to match the contents of objects dynamically, without having to do it manually one by one, with reflection or something similar?

It may even seem more complicated to create a method than to move line by line, but would like something like IgualarConteúdo(origem, destino) .

I'm using classes generated by EntityFramework through the database.

    
asked by anonymous 26.11.2014 / 14:23

2 answers

1

Hello,

There is a simple way to 'Inject' information from one object to another, there is an API called ValueInjecter, which does what you want. In a simple way, the ValueInjecter checks which fields have the same name between two objects and then transfer their values to an object.

Example usage:

Include the API namespace.

  

using Omu.ValueInjecter;

After this, inject the information through the InjectFrom extension.

objetoQueIraReceberOsDados.InjectFrom(objetoQueJaPossuiOsDados);

However, there are examples of what else you can do with it at link

    
26.11.2014 / 18:54
1

I do not know how you're dealing with competition in your project, but it does not seem to me to be the safest way the way you're doing.

If you are working in a multiuser environment and multiple people get the same log (almost) at the same time, take some time to upgrade, if you are not dealing with the competition, the last person you save will always win from the others .

But back to your question, your (row) object should be Untracked . The best way to do this might not be to get the object back, setting column by column and then saving, it would be better to get entities without tracking. This article is great for explaining ways to do this.

  // quando obter a entidade, obtenha assim....
  var entidadeOrinal = Context.MinhaColecao
                              .AsNoTracking()
                              .FirstOrDefault(e => e.Id == 1);

  // (...)
  // aqui você deixa ser usado no seu MVC, WPF... 

  // na hora de salvar, faça isso (sem copiar)
  Context.MinhaColecao.Add(originalEntity);
  Context.SaveChanges();

The trick here is to make the context do not track the modifications. He will find it to be a new but modified entity. The cool thing about it is that it will eventually discover all the associated objects (daughter-tables) and update all of them in the database as well.

I did not enter into competition details here, but I believe it would be important for you to give one investigated. If the system is multiuser, either it will fail constantly or there will be a continuous loss of information.

EDITION

Doing a search, I found this answer: link

There are two ways to copy.

  • Serialization

      private static T DataContractSerialization<T>(T entidade) {
          DataContractSerializer dcSer = new DataContractSerializer(entidade.GetType());
          MemoryStream memoryStream = new MemoryStream();
    
          dcSer.WriteObject(memoryStream, entidade);
          memoryStream.Position = 0;
    
          T entidadeCopiada = (T)dcSer.ReadObject(memoryStream);
          return entidadeCopiada;
      }
    
  • Reflection - In this case, you must follow the article: link

  • 26.11.2014 / 14:58