What is the best technique to use Viewmodel with C#mvc lists?

Asked

Viewed 139 times

2

I have two templates: event registration package and registration package, where the event registration package template has a list of registration packages (see code below, removed some fields).

//Model
public class PacoteInscricaoEvento
{
    public PacoteInscricaoEvento()
    {
        PacoteIncricao = new List<PacoteIncricao>();
    }
    public int PacoteInscricaoEventoId { get; set; }
    public short Nrvagas { get; set; }       
    public IList<PacoteIncricao> PacoteIncricao { get; set; }
}

public class PacoteIncricao
{
    public int PacoteIncricaoId { get; set; }
    public string NmpacoteIncricao { get; set; }
}

Soon, I created two views models, one for each model (code below), among other methods implements the abstract methods copy view and copy model from the Viewmodel abstract class to facilitate the conversion process between the model-to-model view and vice versa.

public class PacoteInscricaoEventoViewModel : ViewModel<PacoteInscricaoEventoViewModel, PacoteInscricaoEvento>
{
    public PacoteInscricaoEventoViewModel()
    {
        PacoteIncricaoViewModel = new List<PacoteIncricaoViewModel>();    
    }

    [Display(Name = "Código")]
    public int PacoteInscricaoEventoId { get; set; }
    [Required]
    [Display(Name = "Nº de Vagas")]
    [Range(1, int.MaxValue)]
    public short Nrvagas { get; set; }
    public List<PacoteIncricaoViewModel> PacoteIncricaoViewModel { get; set; }
    public override PacoteInscricaoEvento CopiarModelo(PacoteInscricaoEvento modelo)
    {
        int indiceElemento = 0;
        modelo.PacoteInscricaoEventoId = this.PacoteInscricaoEventoId;
        modelo.Nrvagas = this.Nrvagas;
        //listas
        //Excluindo os pacotes que foram exluidos na viewmodel no modelo
        if (modelo.PacoteIncricao != null && modelo.PacoteIncricao.Count > 0)
        {
            foreach (PacoteIncricao pacoteIncricaoModelo in modelo.PacoteIncricao)
            {
                //buscando o indice na view model
                indiceElemento = this.PacoteIncricaoViewModel.FindIndex(x => x.PacoteIncricaoId == pacoteIncricaoModelo.PacoteIncricaoId);
                if (indiceElemento == -1)
                    modelo.PacoteIncricao.Remove(pacoteIncricaoModelo);//se nao encontrar exclui
            }
        }
        //adcionando ou alterando os elementos nas view models
        if (this.PacoteIncricaoViewModel != null && this.PacoteIncricaoViewModel.Count > 0)
        {
            foreach (PacoteIncricaoViewModel pacoteInscricaoVM in this.PacoteIncricaoViewModel)
            {
                //buscando o indice no modelo
                indiceElemento = modelo.PacoteIncricao.ToList().FindIndex(x => x.PacoteIncricaoId == pacoteInscricaoVM.PacoteIncricaoId);
                if (indiceElemento == -1) //se nao encontrou altera
                    modelo.PacoteIncricao.Add(pacoteInscricaoVM.CopiarModelo(new PacoteIncricao()));
                else //senao altera o elemento
                    pacoteInscricaoVM.CopiarModelo(modelo.PacoteIncricao[indiceElemento]);
            }
        }
        return modelo;
    }
    public override PacoteInscricaoEventoViewModel CopiarView(PacoteInscricaoEvento modelo)
    {
        this.PacoteInscricaoEventoId = modelo.PacoteInscricaoEventoId;
        this.Nrvagas = modelo.Nrvagas;
        //listas
        foreach (PacoteIncricao pacoteinscricaotmp in modelo.PacoteIncricao)
        {
            this.PacoteIncricaoViewModel.Add(new PacoteIncricaoViewModel().CopiarView(pacoteinscricaotmp));
        }
        return this;
    }
}

public class PacoteIncricaoViewModel : ViewModel<PacoteIncricaoViewModel, PacoteIncricao>
{  
    [Display(Name = "Código")]
    public int PacoteIncricaoId { get; set; }
    [Required]
    [Display(Name = "Nome Pacote")]
    [StringLength(50)]
    public string NmpacoteIncricao { get; set; }             
    public override PacoteIncricao CopiarModelo(PacoteIncricao modelo)
    {
        modelo.PacoteIncricaoId = this.PacoteIncricaoId;
        modelo.NmpacoteIncricao = this.NmpacoteIncricao;
        return modelo;
    }   
    public override PacoteIncricaoViewModel CopiarView(PacoteIncricao modelo)
    {
        this.PacoteIncricaoId = modelo.PacoteIncricaoId;
        this.NmpacoteIncricao = modelo.NmpacoteIncricao;
        return this;
    }
}

So, what is the best technique (or code examples) to create views models that contain views models in this situation (lists), without using automapper or similar? Thank you

  • Dude, use Automapper: http://automapper.org/, will change your life. Tomorrow set an example for you.

  • Dude, I tried to use it a PJ I’m writing and gave a lot of dick, with the references in Entity framework 7 at the time of editing the data (edit). It was as if Entity did not treat the data converted by auto mapper coming from views as the same, losing its references, when it deleted an item from a list as an inscription package for example in the VM and added others, Entity persisted the new and brought the excluded again, so had to do a lot of stuff eventually giving up man.

  • Man, by your code I see some problems of responsibility of the view model, for what it serves the method CopiarModelo? Automapper delivers the ready-made object for you to send to the Service for example or the other way around, takes a DTO and transforms it into a view model. It does this in a very simple way, just that the names of the properties are the same, in case they are different you can create a Factory that makes this conversion for you.

  • The copy then serves to make the process that the auto mapper makes that is to convert the data. Because it is giving a lot of stick in Entity framework 7 at the time of editing the object.

  • Take a look at this example: https://gist.github.com/paulodiogo/c413ead2dfc58feda9a7a139e2578a

  • In the case of the Entity framework, how are you doing? Do you receive the entity directly from the view? It would not be better to read the database entity and change it with the data it is receiving from the view?

  • Damn it, Paulo, I’m gonna take a look at the code you posted for me, my nigga. I did so without taking the bank right in the views q predictor make a contract since all the views will do the same thing ( replacing the auto mapper, I would very much like it to work with me)

  • You send the object that is generated directly to the bank?

  • I’ll see if I can put a chunk of the code in Github and pass you the link, but I already took out the automapper. It might be?

  • put it there and send me...

Show 5 more comments
No answers

Browser other questions tagged

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