在线投票开发:如何统计各选项重复响应及展示得票数
搞定在线投票系统的得票统计与展示
嘿,我仔细看了你的代码和需求,发现当前控制器里的逻辑有不少问题(比如那些a.Id == a.Id的条件根本起不到筛选作用,会直接拿第一条数据),咱们一步步调整,实现你要的「选项#1获得X票」格式展示:
第一步:修正控制器,正确统计每个选项的得票数
首先,咱们得明确:要统计某个投票问题下每个选项的得票数,所以控制器最好接收questionId作为参数,这样能精准定位到要查看结果的投票。然后用LINQ直接在数据库层面统计票数,效率更高:
public async Task<ActionResult> Results(int questionId) { using (var poolDbContext = new PoolContext()) { // 获取指定问题,同时统计每个选项的得票数 var questionStats = await poolDbContext.Questions .Include(q => q.Answers) .AsNoTracking() .Where(q => q.Id == questionId) .Select(q => new { Question = q, AnswerStats = q.Answers.Select(a => new { AnswerId = a.Id, AnswerText = a.Text, VoteCount = poolDbContext.Votes.Count(v => v.AnswerId == a.Id) }) }) .SingleOrDefaultAsync(); if (questionStats == null) { return NotFound(); // 找不到对应问题就返回404 } // 封装成ViewModel传递给视图(推荐用ViewModel,数据更清晰) var viewModel = new ResultsViewModel { Question = questionStats.Question, AnswerResults = questionStats.AnswerStats.Select(stat => new AnswerResultViewModel { AnswerId = stat.AnswerId, AnswerText = stat.AnswerText, VoteCount = stat.VoteCount }).ToList() }; return View(viewModel); } }
这段代码的关键点:
- 用
questionId参数指定要查看的投票,符合实际业务逻辑 - 通过
Select投影出每个选项的ID、文本和对应的投票数,数据库层面统计比拉取所有投票再统计更高效 AsNoTracking()提升查询性能,因为咱们只是读数据不需要修改
第二步:创建专用的ViewModel(推荐)
为了让视图和控制器之间的数据传递更清晰,建议创建两个ViewModel类:
// 单个选项的统计结果 public class AnswerResultViewModel { public int AnswerId { get; set; } public string AnswerText { get; set; } public int VoteCount { get; set; } } // 投票结果页面的整体视图模型 public class ResultsViewModel { public Question Question { get; set; } public List<AnswerResultViewModel> AnswerResults { get; set; } }
第三步:在视图里实现你要的展示格式
假设你的视图是强类型视图(基于ResultsViewModel),直接循环渲染每个选项的结果就行:
@model ResultsViewModel <h2>@Model.Question.Text 的投票结果</h2> @foreach (var result in Model.AnswerResults) { <p><strong>选项#@result.AnswerId 获得 @result.VoteCount 票</strong></p> }
如果暂时不想用ViewModel,也可以用匿名对象传递,视图用dynamic类型,代码差不多:
@model dynamic <h2>@Model.Question.Text 的投票结果</h2> @foreach (var result in Model.AnswerStats) { <p><strong>选项#@result.AnswerId 获得 @result.VoteCount 票</strong></p> }
几个额外的小建议
- 你的
Vote模型里IpAdress拼写错啦,应该是IpAddress - 如果要防止同一IP重复投票,可以在提交投票时检查该IP是否已经给当前问题投过票
- 要是想用导航属性统计票数,也可以写成
a.Votes.Count,但前提是要加载关联的投票数据,不过数据库层面的Count()查询效率更高哦
内容的提问来源于stack exchange,提问作者Dorin Munreanu
相关产品推荐
相关产品推荐

