如何按对象列表进行分组,并将此列表声明为viewmodel的属性

时间:2017-05-19 19:27:05

标签: c# asp.net asp.net-mvc linq

基本上我有这个班级

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; }
}

我正在尝试像这样构建一个ViewModelClass

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

这是控制器的代码,我将根据TipoDeGasto构建一个Gasto列表

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();

正如您所看到的,变量“GD”是带有Listo Gasto的字符串列表(TipoGasto)。

¿问题(问题)是GD如何将其声明为viewModelClass的属性?

我为ViewModel尝试了类似的东西

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

但是有些不对劲。错误的输出说:

  

使用泛型类型List需要1个类型参数

这是分组后的输出 enter image description here

最后解决方案@Ziv Weissman说不使用匿名类型

所以我创建了一个这样的类

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

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

然后在控制器中创建分组列表时我做了这个

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();

感谢所有人的帮助。

3 个答案:

答案 0 :(得分:2)

您不能声明匿名类型的变量:

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

您必须创建另一个具有这两个道具的类。 (或使用KeyValuePair)

像 -

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

然后你可以创建一个强大的类型道具。

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

}

答案 1 :(得分:1)

简单回答,只需在文档中查找GroupBy(),然后查看它返回的内容:

IEnumerable<IGrouping<TKey, TElement>> 

你的情况是:

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

更新: 在GroupBy()之后没有注意到select。试试这个:

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

然后

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

最后:

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

答案 2 :(得分:1)

首先,看起来你想要一本字典,而不是一个列表:

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

其次,具有两列的选择列表会给你带来麻烦,因为它是一个匿名类型,你无法声明一个包含它的字典。相反,只需返回对象:

GD

现在你有了grp,它可以让你枚举foreach (var grp in GD) dictaGastosAgrupada.Add(grp.Key, grp.ToList()); 个对象的列表。您可以将它们添加到字典中,如下所示:

% Input:
list = {'01-Sep-1882'; ...
        '01-Aug-1895'; ...
        '04/01/1912'; ...
        'Tue, 05/28/46'; ...
        'Tue, 03/10/53'; ...
        '06/20/58'; ...
        'Thu, 09/20/73'; ...
        'Fri, 08/15/75'; ...
        'Sun, 12/01/1996'};

% Conversion code:
dt = datetime(list, 'Format', 'dd-MMM-yyyy');
index = isnat(dt);
dt(index) = datetime(list(index), 'Format', 'MM/dd/yy', 'PivotYear', 1900);
index = isnat(dt);
dt(index) = datetime(list(index), 'Format', 'eee, MM/dd/yy', 'PivotYear', 1900)

% Output:
dt = 

  9×1 datetime array

   01-Sep-1882
   01-Aug-1895
   01-Apr-1912
   28-May-1946
   10-Mar-1953
   20-Jun-1958
   20-Sep-1973
   15-Aug-1975
   01-Dec-1996