【问题标题】:How to show aggregate data while using Model.GroupBy in MVC views?在 MVC 视图中使用 Model.GroupBy 时如何显示聚合数据?
【发布时间】:2014-04-27 22:46:41
【问题描述】:

除了视图中的详细信息行之外,我还想显示一些汇总数据,例如“计数”和“总和”。 我有一个拣货清单表,除了显示按 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 代码块,但不知道在哪里放置聚合(求和)函数:

@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>
                            .........
                            .........
                            .........

我怎样才能做到这一点?

【问题讨论】:

  • 您是否正在查看视图代码中的何处/如何从所需的输出示例中写出“12 件”和“10 件”?

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


【解决方案1】:

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

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

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

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

如果您有任何后续问题,请告诉我。希望这会有所帮助。

【讨论】:

  • 感谢您的友好回复。您能否详细说明 ViewModel 方法?请记住,我想显示领料单行的详细信息,同时我想计算每个组或家庭的小计。
  • 当然。您能否添加您当前的模型和您想要实现的 UI 视觉效果。您可以使用该信息编辑您的帖子。
  • 根据您的要求,为了清楚起见,我修改了原来的帖子:)
  • 我已经修改了我的答案以包含视图模型方法的示例。请看一看。
  • 谢谢 SBirthare:) 我现在可以看到路径了。我想我会花几天时间来熟悉 ViewModel。
【解决方案2】:

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

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

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

【讨论】:

  • 丹,我已经尝试过这个选项。我收到以下错误消息:模板只能用于字段访问、属性访问、单维数组索引或单参数自定义索引器表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多