Match content of two objects

Asked

Viewed 483 times

0

Use the method below 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();

It would have to create a method to match the contents of objects dynamically, without having to be done 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 I would like something like this IgualarConteúdo(origem, destino).

I am using classes generated by Entityframework through the database.

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. Simply put, Valueinjecter checks which fields have the same name between two objects and then transfers their values to an object.

Example of use:

Include the API namespace.

using Omu.Valueinjecter;

After that, inject the information through the Injectfrom extension.

objetoQueIraReceberOsDados.InjectFrom(objetoQueJaPossuiOsDados);

Anyway, there are examples of what else you can do with it in https://github.com/omuleanu/ValueInjecter

  • Thanks, very simple, thank you!

1

I don’t know how you’re dealing with competition in your project, but it doesn’t seem to me to be the safest way the way you’re doing.

If you’re working in a multi-user environment and multiple people take the same record (almost) at the same time, take time to update, if you’re not dealing with the competition, the last person you save will always beat the others.

But back to your question, your object (Row) should be Untracked. The best way to do this might not be to get the object again, by setting column by column and then saving, it would be better to get entities without tracking. This article is great to explain 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 not track the modifications. It will think it is a new but modified entity. The cool thing is that it will end up discovering all the associated objects (daughter tables) and updating all of them in the bank as well.

I didn’t go into the details of the competition here, but I think it would be important for you to investigate. If the system is multi-user, either it will constantly fail or there will be a continuous loss of information.

EDITION

Doing a survey, I found this answer: https://stackoverflow.com/questions/2185155/cloning-data-on-entity-framework

There are two ways to make the copy.

  1. 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;
      }
    
  2. Reflection - In this case, it is necessary to accompany Article: http://blogs.msmvps.com/matthieu/2008/05/31/entity-cloner/

  • Thank you for answering. I will research on competition and Untracked. Even now not being a good practice the example posted, would have to match objects without being item by item? Just out of curiosity.

  • @Jotajotajota I think the idea of the code that I passed on would be to just not make that copy, knowing that you’re using a method for altering entities. In the above example you would need to change the way you obtain the object before it is edited (somewhere you bind or get the information that is not detailed in the code above) and change its "alterBem" function to use the above lines without having to make a copy. Even so I found a good article about a guy who did a job that does it, but internally on. Net you will not find any simple way to do.

  • I will change my post above with this information. The most complicated is not simply copying the columns themselves, but treating cases with daughter tables, which the above code would already handle easier (example an entity with "goods" with a daughter table of "tags" for that good).

  • Thanks again! I will research further and refine the way with this implemented.

Browser other questions tagged

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