You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在线投票开发:如何统计各选项重复响应及展示得票数

搞定在线投票系统的得票统计与展示

嘿,我仔细看了你的代码和需求,发现当前控制器里的逻辑有不少问题(比如那些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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:18:31