Click here to Skip to main content
15,895,084 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all

Could you please help me how to display for each user the total spending

UserRecords table
C#
+-------+------+--------------+
|Id     | Name | Cost         |
+-------+------+--------------+
|   1   | Anna |   30.3       |
+-------+------+--------------+
|   2   | Anna |   500        |
+-------+------+--------------+
|   3   | Sam  |   30.3       |
+-------+------+--------------+
|   4   | Tom  |   20.5       |
+-------+------+--------------+
|   5   | Tom  |   20.5       |
+-------+------+--------------+
|   6   | Anna |   20.5       |
+-------+------+--------------+


desire result how to display in web page MVC

Anna  550.8  
Sam    30.3
Tom    41

Total 622.1

Thank you ;)


What I have tried:

C#
public ActionResult Index()
{
  //Disply user and cost 
  var userNameGroup = db.UserRecords.GroupBy(c=>c.Name);
 foreach (var group in userNameGroup)
   {
                var result = ("{0} -{1}", group.Key, group.Max(s => s.Cost));
   }

 return View(db.UserRecords.GroupBy(x=>x.UserNames).ToList());
        }

//how to go from this to the webpage display


HTML
@model IEnumerable<MobileReports.Models.UserRecord>
<table class="table">
    @if (!Model.Any())
    {
        @Html.LabelForModel("Not data uploaded yet")
    }
    else
    {
        <tr>

            
            <th>
                @Html.DisplayNameFor(model => model.Cost)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>

           
            <th></th>
        </tr>

        foreach (var item in Model)
        {
            <tr>
                
                <td>
                    @Html.DisplayFor(modelItem => item.Cost)
                </td>

                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>

               
                <td>                  
                    @Html.DisplayFor(modelItem => item.Total)
                </td>
            </tr>
        }
    }

</table>
Posted
Updated 21-Mar-19 4:47am
Comments
Maciej Los 21-Mar-19 7:35am    
What MVC version? MVC 3, MVC 4, MVC for Core .NET?

Your view expects the model to be IEnumerable<UserRecord>, but your action is passing an IEnumerable<IGrouping<string, UserRecord>>. You need to make the types match.

One simple option would be to group the records in the view:
C#
public ActionResult Index()
{
    return View(db.UserRecords.ToList());
}
Razor
@model IEnumerable<MobileReports.Models.UserRecord>
@if (!Model.Any())
{
    <p>No data uploaded yet.</p>
}
else
{
    <table>
    <thead>
    <tr>
        <th scope="col">Name</th>
        <th scope="col">Cost</th>
    </tr>
    </thead>
    <tfoot>
    <tr>
        <th scope="row">Total:</th>
        <td>@Html.DisplayFor(m => m.Sum(u => u.Cost))</td>
    <tr>
    </tfoot>
    <tbody>
    @foreach (var item in Model.GroupBy(u => u.Name, (key, items) => new { Name = key, Cost = items.Sum(u => u.Cost) }))
    {
        <tr>
            <th scope="row">@Html.DisplayFor(_ => item.Name)</th>
            <th scope="row">@Html.DisplayFor(_ => item.Cost)</th>
        </tr>
    }
    </tbody>
    </table>
}

A cleaner approach would be to create a view-model to represent the grouped results. Populate the view-model in the action, and change the view to use the view-model.
C#
public class UserCostsViewModel
{
    public string Name { get; set; }
    public decimal Cost { get; set; }
}

public class GroupedUserCostsViewModel
{
    public IReadOnlyList<UserCostsViewModel> Items { get; set; }
    public decimal Total { get; set; }
}
C#
public ActionResult Index()
{
    var source = db.UserRecords.ToList();
    
    var items = source
        .GroupBy(u => u.Name, (key, items) => new UserCostsViewModel
        {
            Name = key,
            Cost = items.Sum(u => u.Cost)
        })
        .ToList();
    
    var model = new GroupedUserCostsViewModel
    {
        Items = items,
        Total = source.Sum(u => u.Cost)
    };
    
    return View(model);
}
Razor
@model GroupedUserCostsViewModel
@if (!Model.Items.Any())
{
    <p>No data uploaded yet.</p>
}
else
{
    <table>
    <thead>
    <tr>
        <th scope="col">Name</th>
        <th scope="col">Cost</th>
    </tr>
    </thead>
    <tfoot>
    <tr>
        <th scope="row">Total:</th>
        <td>@Html.DisplayFor(m => m.Total)</td>
    <tr>
    </tfoot>
    <tbody>
    @foreach (var item in Model.Items)
    {
        <tr>
            <th scope="row">@Html.DisplayFor(_ => item.Name)</th>
            <th scope="row">@Html.DisplayFor(_ => item.Cost)</th>
        </tr>
    }
    </tbody>
    </table>
}
 
Share this answer
 
Comments
Maciej Los 21-Mar-19 15:00pm    
Oops... I missed your answer earlier...
5ed!
I'd suggest to create another model TotalUserData
C#
public class TotalUserData
{
    public string Name
    {
        get;
        set;
    }

    public double TotalCost
    {
        get;
        set;
    }
}

and a controller for above model.

Then...

public ActionResult Index()
{
  //Display user and cost 
  var userNameGroup = db.UserRecords
        .GroupBy(c=>c.Name)
        .Select(grp=> new TotalUserData(Name=grp.Key, Total=grp.Sum(x=>x.Cost)))
        .ToList();

  return View(userNameGroup);
}


Finally, change View to be able to display corresponding data.

HTML
@model IEnumerable<MvcApplication1.Models.TotalUserData>

@{
    ViewBag.Title = "Total";
}

<h2>Total</h2>
<table class="table">
    @if (!Model.Any())
    {
        @Html.LabelForModel("Not data uploaded yet")
    }
    else
    {
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TotalCost)
            </th>
            @*<th>Action</th>*@
        </tr>

        foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>                  
                    @Html.DisplayFor(modelItem => item.TotalCost)
                </td>
            </tr>
        }
        <tr><td colspan="2">Total of total: @Model.Sum(x=>x.TotalCost)</td></tr>
    }
</table>
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900