Isma Haro
Isma Haro

Reputation: 263

How to group by a list of objects and declare this list as an attribute of a viewmodel

Basically I have this class

public class Gasto
{
    public int IdTienda { get; set; }
    public int IdGasto { get; set; }
    public System.DateTime Fecha { get; set; }
    public string ConceptoDeGasto { get; set; }
    public double Total { get; set; }
    public string TipoDeGasto { get; set; }
    public Nullable<int> IdVenta { get; set; }
    public Nullable<System.DateTime> FechaVenta { get; set; }

    public virtual Tienda Tienda { get; set; }
}

And I'm trying to build a ViewModelClass like this

public class CorteConVentas
{
    // STILL NO ATRIBUTE -- THIS IS THE QUESTION
}

Here is the code for the controller where I will build a List of Gasto grouped by TipoDeGasto

var gastos = db.Gastos.Where(g => g.IdGasto >= corte.DesdeIdGasto && g.IdGasto <= corte.HastaIdGasto).ToList();

var GD     = gastos.GroupBy(u => u.TipoDeGasto).Select(grp => new { TipoGasto = grp.Key, gastos = grp.ToList() } ).ToList();

As you can see the variable "GD" is a List of Strings (TipoGasto) with List of Gasto.

¿The issue (question) is this GD how can I declare it as an attribute of my viewModelClass?

I tried something like this for the ViewModel

public class CorteConVentas
{
    public List<string, List<Gasto>> listaGastosAgrupada { get; set; }
}

But there is something wrong. The output of the error says:

Using the generic type List requires 1 type arguments

Here is the output after grouping by enter image description here

Finally the solution as @Ziv Weissman said was not to use an anonymous type

So I created a class like this

public class CorteConVentas
{
    public List<GastosAgrupados> listaGastosAgrupada { get; set; }
}

public class GastosAgrupados
{
    public string TipoGasto { get; set; }
    public List<Gasto> gastos { get; set;}
}

And then in the controller when creating the grouped list I did this

var gastos = db.Gastos.Where(g => g.IdGasto >= corte.DesdeIdGasto && g.IdGasto <= corte.HastaIdGasto).ToList();

var gd     = gastos.GroupBy(u => u.TipoDeGasto).Select(grp => new GastosAgrupados { TipoGasto = grp.Key, gastos = grp.ToList()) } ).ToList();

Thanks to all for helping me.

Upvotes: 2

Views: 2354

Answers (3)

John Wu
John Wu

Reputation: 52210

First, looks like you want a dictionary, not a list:

public class CorteConVentas
{
    public Dictionary<string, List<Gasto>> dictaGastosAgrupada { get; set; }
}

Second, that select list with two columns is going to give you trouble because it comes out as an anonymous type, and you have no way to declare a dictionary that will contain it. Instead, just return the object:

var GD = gastos.GroupBy(u => u.TipoDeGasto).Select(grp);

So now you have GD which will let you enumerate over a list of grp objects. You can add them to your dictionary like this:

foreach (var grp in GD) dictaGastosAgrupada.Add(grp.Key, grp.ToList());

Upvotes: 1

Ziv Weissman
Ziv Weissman

Reputation: 4516

You cannot declare a variable of anonymous type:

.Select(grp => new { TipoGasto = grp.Key, gastos = grp.ToList() } )

You must create another class which has these two props. (or use a KeyValuePair)

Something like -

.Select(grp => new KeyValuePair<string,List<Gasto>> { Key = grp.Key, Value = grp.ToList() } )

Then you can create a strong typed prop.

public class CorteConVentas
{
  List<KeyValuePair<string,List<Gasto>>> PropName {get; set;}

}

Upvotes: 2

James Curran
James Curran

Reputation: 103485

Simple answer, just look up GroupBy() in the docs, and see what it returns:

IEnumerable<IGrouping<TKey, TElement>> 

which is your case would be:

 public class CorteConVentas
 {
    public IEnumerable<IGrouping<string, Gasto>> listaGastosAgrupada { get; set; }
 }

Update: Didn't notice the select after the GroupBy(). Try this:

public class GrupoGastos   // forgive my attempts at Spanish via Google Translate
{
     public string TipoGasto {get; set;}
     public List<Gasto> Gastos {get; set;}
}

then

var GD     = gastos.GroupBy(u => u.TipoDeGasto)
             .Select(grp => new GrupoGastos  
                  { TipoGasto = grp.Key, Gastos = grp.ToList() } )
             .ToList();

and finally:

public class CorteConVentas
{
    public List<GrupoGastos> listaGastosAgrupada { get; set; }
}

Upvotes: 1

Related Questions