What better way to save a Group object that has Items lists?

Asked

Viewed 1,368 times

4

I have a record and in it there are several links, for example:

public class Grupo {
   public string Nome {get;set;}
   public List<GrupoItemA> ItensA {get;set;}
   public List<GrupoItemB> ItensB {get;set;}
   public List<GrupoItemC> ItensC {get;set;}
}
public class GrupoItemB {
   public Grupo Grupo {get;set;}
   public ItemA Item {get;set;}
   public string Observacao {get;set;}
}

I have defined my classes.

My question is, I want the user to be able to link all the Items in the View and only when sending the POST to save everything, that is, save the Group and then the Items classes.

What would be the best way to do that?

I thought about Session, but I was told that is not good practice and can get heavy if there are many items.

I thought to store everything in Array in Javascript, but in case of error or something, it will lose everything.

Or in some static class

How could I get better result in this case?

  • I think the ideal would be to use JS to write to HTML. If I have more time I reply later.

3 answers

3

You need to receive Group and Group Items data when the user gives the Post.

I don’t know if it’s the best, but an alternative (I’ve used several times) to this is you can create a Model (as Grupoviewmodel for example) that will have properties like lists/arrays to receive the Ids of each list of items that your user selected for the Group, in addition to the Group data (with Id, Name...) and the name of the items, etc.

Example of Model:

public class GrupoViewModel
{           
    private IRepositorioItem _repositorioItem;

    public GrupoViewModel(IRepositorioItem repositorioItem)
    {
        _repositorioItem = repositorioItem;
    }

    public GrupoViewModel():this()
    {
        PreencherListaDeGrupoItemA();
        PreencherListaDeGrupoItemB();
        PreencherListaDeGrupoItemC();
    }

    //Dados do Grupo
    public int ID { get; set; }
    public string Nome { get; set; }

    //Outros campos do seu model.....

    //Lista de Itens
    public int[] IdsGrupoItemA { get; set; }
    public int[] IdsGrupoItemB { get; set; }
    public int[] IdsGrupoItemC { get; set; }

    private void PreencherListaDeGrupoItemA()
    {
        //Código para buscar e preencher os itens IdsGrupoItemA 
        foreach(var item in _repositorioItem.ObterTodosGrupoItemA())
        {
           //Preenche os dados desejados como IdsGrupoItemA do item, etc...
        }
    }

    private void PreencherListaDeGrupoItemB()
    {
        //Código para buscar e preencher os itens IdsGrupoItemB 
        foreach(var item in _repositorioItem.ObterTodosGrupoItemB())
        {
           //Preenche os dados desejados como IdsGrupoItemB do item, etc...
        }
    }

    private void PreencherListaDeGrupoItemC()
    {
        //Código para buscar e preencher os itens IdsGrupoItemC 
        foreach(var item in _repositorioItem.ObterTodosGrupoItemC())
        {
           //Preenche os dados desejados como IdsGrupoItemC do item, etc...
        }
    }
}

In the Controller, in his Action of Get, you create an instance of Grupoviewmodel filling in the information to be submitted (Group data and list of items).

To ride his View (of the kind Grupoviewmodel) use the Item Ids, which will already be filled in, using checkbox (what I normally use) with the same name of the properties for the user to select the desired items.

In the Controller, in his Action Post, you receive the Ids of the items selected by the user, for each Id you retrieve the object (be it Groupoitema, Groupoitemb and/or Groupoitemc) and associate/add in the item list of your Group.

Example Controller:

public class GrupoController
{
    public ActionResult Create()
    {                    
       return View(new GrupoViewModel());
    }

    [HttpPost]
    public ActionResult Create(GrupoViewModel grupoViewModel)
    {
        ...
        List<GrupoItemA> listaItensAselecionados = new List<GrupoItemA>();
        foreach(var idGrupoItemA in grupoViewModel.IdsGrupoItemA)
        {
            //Recupero o objeto GrupoItemA desse Id e adiciono na lista listaItensAselecionados 
        }

        List<GrupoItemB> listaItensBselecionados = new List<GrupoItemB>();
        foreach(var idGrupoItemB in grupoViewModel.IdsGrupoItemB)
        {
            //Recupero o objeto GrupoItemB desse Id e adiciono na lista listaItensBselecionados 
        }

        List<GrupoItemC> listaItensCselecionados = new List<GrupoItemC>();
        foreach(var idGrupoItemC in grupoViewModel.IdsGrupoItemC)
        {
            //Recupero o objeto GrupoItemC desse Id e adiciono na lista listaItensCselecionados 
        }

        ...

        //Agora com os itens selecionados recuperados você cria o Grupo novo
    }
}
  • Hello Renan, I understood your answer, but I think I’m more difficult to fill them in the view, just like you, I also use checkbox, but, when clicking the checkbox I open a modal to insert other additional information...

  • @Rod understood, but then I recommend you open a specific question about the situation of this modal (that was not in the question rs) to try to help you (you could even put the link of this question as reference). The answers here focus on your initial question about how to save a Group object that has Item lists.

2


My question is, I want the user to be able to link all the Items in the View and only when sending the POST to save everything, that is, save the Group and then the Items classes. What would be the best way to do that?

Typing HTML into View. But it can’t be any HTML.

For this answer, I’m guessing you know how to use the Begincollectionitem, a Nuget package made to manipulate master-detail. It has 4 answers of mine on it:

Another thing is that it is not good practice to use List because List is an object with limited properties. The recommended way to use as Model is:

[DisplayColumn("Nome")]
public class Grupo 
{
    [Key]
    public int GrupoId { get; set; }
    public string Nome { get; set; }

    public ICollection<GrupoItemA> ItensA {get;set;}
    public ICollection<GrupoItemB> ItensB {get;set;}
    public ICollection<GrupoItemC> ItensC {get;set;}
}

If there are any further questions, please let me know.

  • I don’t know Begincollectionitem yet, I’m curious and then take a look. I just don’t understand why you say "it’s not good practice to use List". I’ve used many times without problems.

  • Because a List does not have several methods that Collection has, for example, methods that can be extended and improved to the need of the application.

  • I understood and I agree. But depending on the scenario the List fits very well. I sweated a little when I read that it is not good practice to use rs. So it depends on what you need. Thanks for the return.

  • Good that it sounded, because this is the message. The ideal is always to use interfaces so that the model is as elastic as possible.

  • Gypsy, thanks for the answer(again) the problem of using this Begincollection, is that one of the properties I have is a combobox that contains values that comes from the bank, so would be [Combobox] [Valor1] [Valor2]And I don’t know if it wouldn’t be too heavy if there’s too much of those fields...

  • @Rod Why would I?

  • Many combobox fields with listing... But this lib supports Asp.net mvc 5? I saw there in all the examples, only Asp.net mvc2

  • @Rod has yes. It’s okay to use "many fields with listing". It works the same.

Show 3 more comments

1

Two good strategies would be to use (1) lightweight objects (Objects) and/or (2) caches.

  1. Lightweight objects are objects filled only with the identification and display fields for the user, for example "id" and "Description".

  2. Cache is a form of temporary storage of information and quick access. For . Net you can read about cache here: http://msdn.microsoft.com/en-us/library/dd997357%28v=VS.100%29.aspx

Browser other questions tagged

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