有没有办法使用 Linq 显示结果最高的项目而不重复特定名称?
Is there a way to use Linq to display an item with the highest result without duplication of a specific name?
我正在尝试向我的网站添加一项功能,教师可以在该功能中查看当周完成目标的学生的摘要。
这是我的控制器方法
public IActionResult WeeklyDetails()
{
var user = svc.GetUser(GetSignedInUserId());
var goals = svc.GetGoalsForTeacher(user.Id);
var mostRecentMonday = DateTime.Now.StartOfWeek(DayOfWeek.Monday);//get week start of most recent Monday morning
var weekEnd = mostRecentMonday.AddDays(7).AddSeconds(-1); //will return the end of the day on Sunday
var results = goals.Where(g => g.AchievedOn >= mostRecentMonday && g.AchievedOn <= weekEnd).ToList();
for (int i = 0; i < results.Count; i++)
{
//Get count of current element to before:
int count = results.Take(i + 1)
.Count(r => r.Student.Name == results[i].Student.Name);
results[i].Count = count;
}
var result = results.GroupBy(x => x.Id)
.Select(group => group.First()).ToList();
return View(result);
}
在我的 cshtml 视图页面中,我这样调用详细信息
@foreach(var item in Model)
{
<p>@item.Student.Name @item.Count</p>
}
然而,我得到了这个结果
Emma 1
Emma 2
Sarah 1
这是因为艾玛有两个目标在我知道的列表中完成,但我更希望艾玛 2 是唯一显示的结果。有没有办法先选Max再选第一个?也许不是,如果不清楚,我深表歉意。
我不知道结果的定义,但我认为你是按结果的主键分组的(x.Id)。您使用原始结果列表作为视图的模型。但是你提供聚合数据,所以我会创建一个干净的类型(可以在你的控制器内部完成 class 作为嵌套 class):
public class GoalSummary
{
public int StudentId {get;set;}
public string Firstname {get;set;}
public string Name {get;set;}
public int Goals {get;set;}
}
然后您可以使用分组和投影 (select) 来创建此结果:
var summary = goals
.Where(g => g.AchievedOn >= mostRecentMonday && g.AchievedOn <= weekEnd)
.GroupBy(g => new {g.Student.Id, g.Student.Firstname, g.Student.Name})
.Select(g => new GoalSummary
{
StudentId = g.Key.Id,
Firstname = g.Key.Firstname,
Name = g.Key.Name,
Goals = g.Count()
}).ToList();
return View(summary);
如果您熟悉 SQL:我们需要 StudentId、Firstname、Name 和 COUNT(*)。所以我们必须按 Id、Firstname 和 Name 分组。
在您的视图中,您可以使用您输入的摘要:
@model List<YourNamespace.Controllers.YourController.GoalSummary>
我正在尝试向我的网站添加一项功能,教师可以在该功能中查看当周完成目标的学生的摘要。 这是我的控制器方法
public IActionResult WeeklyDetails()
{
var user = svc.GetUser(GetSignedInUserId());
var goals = svc.GetGoalsForTeacher(user.Id);
var mostRecentMonday = DateTime.Now.StartOfWeek(DayOfWeek.Monday);//get week start of most recent Monday morning
var weekEnd = mostRecentMonday.AddDays(7).AddSeconds(-1); //will return the end of the day on Sunday
var results = goals.Where(g => g.AchievedOn >= mostRecentMonday && g.AchievedOn <= weekEnd).ToList();
for (int i = 0; i < results.Count; i++)
{
//Get count of current element to before:
int count = results.Take(i + 1)
.Count(r => r.Student.Name == results[i].Student.Name);
results[i].Count = count;
}
var result = results.GroupBy(x => x.Id)
.Select(group => group.First()).ToList();
return View(result);
}
在我的 cshtml 视图页面中,我这样调用详细信息
@foreach(var item in Model)
{
<p>@item.Student.Name @item.Count</p>
}
然而,我得到了这个结果
Emma 1
Emma 2
Sarah 1
这是因为艾玛有两个目标在我知道的列表中完成,但我更希望艾玛 2 是唯一显示的结果。有没有办法先选Max再选第一个?也许不是,如果不清楚,我深表歉意。
我不知道结果的定义,但我认为你是按结果的主键分组的(x.Id)。您使用原始结果列表作为视图的模型。但是你提供聚合数据,所以我会创建一个干净的类型(可以在你的控制器内部完成 class 作为嵌套 class):
public class GoalSummary
{
public int StudentId {get;set;}
public string Firstname {get;set;}
public string Name {get;set;}
public int Goals {get;set;}
}
然后您可以使用分组和投影 (select) 来创建此结果:
var summary = goals
.Where(g => g.AchievedOn >= mostRecentMonday && g.AchievedOn <= weekEnd)
.GroupBy(g => new {g.Student.Id, g.Student.Firstname, g.Student.Name})
.Select(g => new GoalSummary
{
StudentId = g.Key.Id,
Firstname = g.Key.Firstname,
Name = g.Key.Name,
Goals = g.Count()
}).ToList();
return View(summary);
如果您熟悉 SQL:我们需要 StudentId、Firstname、Name 和 COUNT(*)。所以我们必须按 Id、Firstname 和 Name 分组。
在您的视图中,您可以使用您输入的摘要:
@model List<YourNamespace.Controllers.YourController.GoalSummary>