如何在MVC视图中使用Model.GroupBy时显示聚合数据?

时间:2014-04-27 22:46:42

标签: asp.net-mvc aggregate asp.net-mvc-views

除了我视图中的详细信息行之外,我还想显示一些汇总数据,例如" count"和"总和"。 我有一个拣货清单表,除了显示由SKU组织的清单行外,我想显示每个SKU的总额。

我的PickingList模型如下所示:

public partial class PickingList
{
    public int Id { get; set; }
    [ForeignKey("List_Header")]
    public int TransID { get; set; }
    public string SKU { get; set; }
    public int ColorId { get; set; }
    public double Qty { get; set; }
    public decimal Price { get; set; }

    public virtual List_Header List_Header { get; set; }
}

我将TransID传递给列表的控制器是:

    public ActionResult ListShipment(int transid)
    {
        var mylist = db.PickingLists.Where(p => p.TransID == transid);
        mylist = mylist.OrderBy(p => p.Id);
        return View(mylist.ToList());
    }

最后,我想要实现的是:

SKU           Qty              Color

61009         12 pieces
               3               Blue
               5               Red
               4               Green

61011         10 pieces
               6               Blue
               4               Red

我已尝试过以下View代码块,但无法确定汇总(sum)函数的放置位置:

@foreach (var group in Model.GroupBy(item => item.SKU))
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => group.Key)
                        </td>
                   </tr>
                    foreach (var item in group.OrderBy(o => o.Id))
                    {
                        <tr>
                            <td></td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Qty)
                            </td>
                            .........
                            .........
                            .........

我怎么能实现这个目标?

2 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解您的要求,但我认为您正在尝试对客户端收到的数据进行一些汇总。如果是这种情况,您可以使用

Linqjs

它非常棒,让您能够在客户端代码中使用.Net方法。

另一种方法是,定义ViewModel并添加QtySum和LineCount属性。在服务器端代码计算并将ViewModel返回给客户端。客户端代码将使用这些值来呈现UI。

更新1:

查看有关您想要实现的内容的更多信息,我确信您肯定希望使用定义ViewModel方法。我更喜欢它,因为它给我更多的控制,因为我正在编写服务器端代码并​​具有所有功能(.net方法)。其次,我更喜欢尽可能保持愚蠢和轻量级的观点。

在您当前的场景中,我将如下定义视图模型(考虑此示例以获取指导并根据您的需要进行修改):

public class PickingListViewModel
{
    public int Id { get; set; }
    public int TransID { get; set; }
    public PickingListSkuViewModel SkuGroupModel { get; set; }
}

public class PickingListSkuViewModel
{
    public string SKU { get; set; }
    public IEnumerable<PickingListItemViewModel> GroupItems { get; set; }
}

public class PickingListItemViewModel
{
    public int ColorId { get; set; }
    public string Color { get; set; }
    public double Qty { get; set; }
    public decimal Price { get; set; }
}

现在在控制器中,我可以像这样填充视图模型(再次注意,首选方法是从业务或数据层获取数据):

public ActionResult Index()
{
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

    // Read this data from business layer
    var group1 = new PickingListSkuViewModel
    {
        SKU = "61009",
        GroupItems = new List<PickingListItemViewModel>
        {
            new PickingListItemViewModel
            {
                Color = "Blue",
                Qty = 12,
                Price = (decimal) 2.5
            },
            new PickingListItemViewModel
            {
                Color = "Red",
                Qty = 3,
                Price = (decimal) 4.5
            }
            ,
            new PickingListItemViewModel
            {
                Color = "Green",
                Qty = 4,
                Price = (decimal) 1.5
            }
        }
    };

    var group2 = new PickingListSkuViewModel
    {
        SKU = "61011",
        GroupItems = new List<PickingListItemViewModel>
        {
            new PickingListItemViewModel
            {
                Color = "Blue",
                Qty = 12,
                Price = (decimal) 2.5
            },
            new PickingListItemViewModel
            {
                Color = "Red",
                Qty = 3,
                Price = (decimal) 4.5
            }
            ,
            new PickingListItemViewModel
            {
                Color = "Green",
                Qty = 4,
                Price = (decimal) 1.5
            }
        }
    };

    var model = new List<PickingListViewModel>
    {
        new PickingListViewModel
        {
            Id = 1,
            TransID = 101,
            SkuGroupModel = group1
        },
        new PickingListViewModel
        {
            Id = 2,
            TransID = 102,
            SkuGroupModel = group2
        }
    };

    return View(model);
}

控制器应该只是初始化模型并将其返回到适当的视图。

我没有包含查看代码,因为我相信您对此感到满意。提示您现在拥有每组的所有信息,只需编写渲染代码即可。您可以将总和或计数或任何其他聚合添加到PickingListItemViewModel中,或者可以对视图代码执行简单计算,例如TotalPrice =数量*价格

如果您有任何跟进问题,请与我们联系。希望这会有所帮助。

答案 1 :(得分:0)

正如SBirthare建议的那样,我认为你应该创建一个视图模型并将其中的一些工作移到那里。但是,要回答你的问题,也许你可能正在寻找以下内容:

<tr>
  <td>
    @Html.DisplayFor(modelItem => group.Key)
  </td>
  <td>
    @Html.DisplayFor(modelItem => group.Sum(item => item.Qty))
    <span> pieces</span>
  </td>
</tr>

如果我误解了你的问题,请告诉我。