c# - 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; }
}
}
解决方案
当您运行一个组时,它会将一个平面的对象列表转换为一个列表列表。像这样的平面列表:
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>
我重命名stat
为stats
概述您正在查看的项目中可能有多个内容,foreach
并且我假设您想要汇总数字统计信息,但也许如果您有其他想法,例如平均,您将不得不更改它
推荐阅读
- python - 熊猫中与范围相关的错误:未绑定的本地错误
- node.js - 意外的长期发布请求 | Heroku
- redis - Yii2 如何禁用 Redis
- electron - 将 Electron .app 包上传到 App Store Connect/Mac App Store
- android - Laravel Firebase 不发送推送通知
- javascript - 使用 JavaScript 出错时更改图像 src
- python - keras 中滚动窗口 LSTM 的自定义拟合和预测循环(时间序列预测)
- python - 在 Python 中使用 API 更新 Google Cloud Function 的标签
- python - 在 python pandas 中组合多个 excel 文件的问题
- algorithm - 给定以下条件,检查一组数字是否满足三元组 (X, Y, Z)