首页 > 解决方案 > GroupBy in cshtml

问题描述

I am trying to groupby the PlayerId in my table but am getting the following error:

'IGrouping<int, Stat>' does not contain a definition for 'Player' and no accessible extension method 'Player' accepting a first argument of type 'IGrouping<int, Stat>' could be found (are you missing a using directive or an assembly reference?)

Any help would be very appreciated.

View

@model IEnumerable<Block_City_Website.Models.Stat>
@using static MoreLinq.Extensions.LagExtension;
@using static MoreLinq.Extensions.LeadExtension;
@using MoreEnumerable = MoreLinq.MoreEnumerable;

<div class="container p-3">
    <div class="row pt-4">
        <div class="col-6">
            <h2 class="text-primary">Stats List</h2>
        </div>
        <div class="col-6 text-right">
            <a asp-controller="Stat" asp-action="Index" class="btn btn-primary">Back to Stats</a>
        </div>
    </div>
    <br />

    @if (Model.Count() > 0)
    {


        <table class="table table-bordered table-striped" style="width:100%">
            <thead>
                <tr>
                    <th>
                        Player
                    </th>
                    <th>
                        Team
                    </th>
                    <th>
                        Points
                    </th>
                    <th>
                        Rebounds
                    </th>
                    <th>
                        Assists
                    </th>
                    <th>
                        Steals
                    </th>
                    <th>
                        Blocks
                    </th>
                </tr>
            </thead>
            <tbody>

                           

                @foreach (var stat in Model.GroupBy(x => x.PlayerId))
                {
                    <tr>
                        <td width="10%">@stat.Player.FirstName @stat.Player.LastName</td>
                        <td width="10%">@stat.Team.TeamName</td>
                        <td width="10%">@stat.Points</td>
                        <td width="10%">@stat.Rebounds</td>
                        <td width="10%">@stat.Assists</td>
                        <td width="10%">@stat.Steals</td>
                        <td width="10%">@stat.Blocks</td>
                    </tr>

                }
            </tbody>
        </table>
    }
    else
    {
        <p>No Stats created yet</p>
    }
</div>
@if (Model.Count() > 0)
{


    <table class="table table-bordered table-striped" style="width:100%">
        <thead>
            <tr>
                <th>
                    Player
                </th>
                <th>
                    Team
                </th>
                <th>
                    Points
                </th>
                <th>
                    Rebounds
                </th>
                <th>
                    Assists
                </th>
                <th>
                    Steals
                </th>
                <th>
                    Blocks
                </th>
            </tr>
        </thead>
        <tbody>

            <tr>
                <td width="10%">Stephen Curry</td>
                <td width="10%">Warriors</td>
                <td width="10%">58</td>
                <td width="10%">15</td>
                <td width="10%">12</td>
                <td width="10%">5</td>
                <td width="10%">3</td>
            </tr>
            <tr>
                <td width="10%">Lebron James</td>
                <td width="10%">Lakers</td>
                <td width="10%">64</td>
                <td width="10%">19</td>
                <td width="10%">17</td>
                <td width="10%">5</td>
                <td width="10%">5</td>
            </tr>


        </tbody>
    </table>
}
else
{
    <p>No Stats created yet</p>
}
<div>

</div>

Controller

using Block_City_Website.Data;
using Block_City_Website.Models;
using Block_City_Website.Models.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Block_City_Website.Controllers
{
    public class StatController : Controller
    {
        private readonly ApplicationDbContext _db;

        public StatController(ApplicationDbContext db)
        {
            _db = db;
        }

        
            public IActionResult Index()
        {



            IEnumerable<Stat> objList = _db.Stats;

            foreach(var obj in objList)
            {
                obj.Player = _db.Players.FirstOrDefault(u => u.Id == obj.PlayerId);
                obj.Team = _db.Teams.FirstOrDefault(u => u.Id == obj.TeamId);


            }

            return View(objList);
        }


        //GET-Create
        public IActionResult Create()
        {
            //IEnumerable<SelectListItem> TypeDropDown = _db.Players.Select(i => new SelectListItem
            //{
            //    Text = i.FirstName + " " +i.LastName,
            //    Value = i.Id.ToString()
            //});

            //ViewBag.TypeDropDown = TypeDropDown;

            StatVM statVM = new StatVM()
            {
                Stat = new Stat(),
                TypeDropDown = _db.Players.Select(i => new SelectListItem
                {
                    Text = i.FirstName + " " + i.LastName,
                    Value = i.Id.ToString()
                }),
                TypeDropDown1 = _db.Teams.Select(i => new SelectListItem
                {
                    Text = i.TeamName,
                    Value = i.Id.ToString()
                })
            };

            return View(statVM);
        }

        //POST-Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(StatVM obj)
        {
            if (ModelState.IsValid)
            {
                //obj.PlayerId = 1;
                //obj.TeamId = 1; 
                _db.Stats.Add(obj.Stat);
                _db.SaveChanges();
                return RedirectToAction("Index");

            }
            return View(obj);
        }

        // GET-Delete
        public IActionResult Delete(int? id)
        {
            if (id == null || id == 0)
            {
                return NotFound();
            }
            var obj = _db.Stats.Find(id);
            if (obj == null)
            {
                return NotFound();
            }
            return View(obj);
        }

        // POST-Delete
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult DeletePost(int? id)
        {
            var obj = _db.Stats.Find(id);
            if (obj == null)
            {
                return NotFound();
            }
            _db.Stats.Remove(obj);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }

        // GET Update
        public IActionResult Update(int? id)
        {
            StatVM expenseVM = new StatVM()
            {
                Stat = new Stat(),
                TypeDropDown = _db.Players.Select(i => new SelectListItem
                {
                    Text = i.FirstName + " " + i.LastName,
                    Value = i.Id.ToString()
                }),
                TypeDropDown1 = _db.Teams.Select(i => new SelectListItem
                {
                    Text = i.TeamName,
                    Value = i.Id.ToString()
                })
            };

            if (id == null || id == 0)
            {
                return NotFound();
            }
            expenseVM.Stat = _db.Stats.Find(id);
            if (expenseVM.Stat == null)
            {
                return NotFound();
            }
            return View(expenseVM);

        }

        // POST UPDATE
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Update(StatVM obj)
        {
            if (ModelState.IsValid)
            {
                _db.Stats.Update(obj.Stat);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(obj);

        }

        public IActionResult TotStats()
        {



            IEnumerable<Stat> objList = _db.Stats;

            foreach (var obj in objList)
            {
                obj.Player = _db.Players.FirstOrDefault(u => u.Id == obj.PlayerId);
                obj.Team = _db.Teams.FirstOrDefault(u => u.Id == obj.TeamId);
            }

            return View(objList);
        }


    }
}

Model

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace Block_City_Website.Models
{
    public class Stat
    {
        [Key]
        public int Id { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage ="Amount must not be less than 0")]
        public int Points { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage = "Amount must not be less than 0")]
        public int Rebounds { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage = "Amount must not be less than 0")]
        public int Assists { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage = "Amount must not be less than 0")]
        public int Steals { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage = "Amount must not be less than 0")]
        public int Blocks { get; set; }

        [Required]
        [DisplayName("Player")]
        public int PlayerId { get; set; }
        [ForeignKey("PlayerId")]
        public virtual Player Player { get; set; }

        [Required]
        [DisplayName("Team")]
        public int TeamId { get; set; }
        [ForeignKey("TeamId")]
        public virtual Team Team { get; set; }
    }
}

标签: c#asp.netrazor

解决方案


当您运行一个组时,它会将一个平面的对象列表转换为一个列表列表。像这样的平面列表:

PlayerScore 
.PlayerId, .GameScore
{1, 20}
{1, 40} 
{1, 60}
{2, 30}
{2, 50}

按 PlayerId 分组,最终看起来像这样:

Key, (list of PlayerScores)
1, [{1,20}, {1,40}, {1,60}]
2, [{2,30}, {2,50}]

所以你需要欣赏的是你的 GroupBy 已经产生了一个列表列表,你不能再直接输出玩家的东西了;stat您正在输入的每个条目foreach本身就是 Stat 对象的集合

这意味着您必须在列表的上下文中做有意义的事情

            foreach (var stats in Model.GroupBy(x => x.PlayerId))
            {
                <tr>
                    <td width="10%">@stats.First().Player.FirstName @stats.First().Player.LastName</td>
                    <td width="10%">@stats.First().Team.TeamName</td>
                    <td width="10%">@stats.Sum(stat => stat.Points)</td>
                    <td width="10%">@stats.Sum(stat => stat.Rebounds)</td>
                    <td width="10%">@stats.Sum(stat => stat.Assists)</td>
                    <td width="10%">@stats.Sum(stat => stat.Steals)</td>
                    <td width="10%">@stats.Sum(stat => stat.Blocks)</td>

我重命名statstats概述您正在查看的项目中可能有多个内容,foreach并且我假设您想要汇总数字统计信息,但也许如果您有其他想法,例如平均,您将不得不更改它


推荐阅读