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

ASP.NET MVC开发考试系统时Question的Answer列表返回null求解

问题原因说明

C#完全支持列表嵌套的结构,该问题和C#语法无关,是Entity Framework(以下简称EF)的配置、映射和数据加载规则导致的,具体有3个核心问题:

  1. 基础类型集合没有正确配置映射:EF默认无法直接将ICollection<string>这类基础类型的集合属性映射到数据库字段,如果你没有做特殊配置,Answer属性的内容在保存试卷时根本不会写入数据库,查询时自然返回null。
  2. 没有开启延迟加载且属性未初始化:Question类的Answer属性没有加virtual关键字,EF的延迟加载机制对非virtual属性不生效;同时你没有在类构造函数中初始化集合属性,实例化Question对象时Answer默认就是null。
  3. 查询时没有显式加载关联数据:你用db.Exams.Find(id)查询试卷时,默认只会加载Exam本身的字段,关联的Questions下的Answer数据不会主动加载。

解决方案

方案1:EF Core环境下直接用JSON序列化存储基础类型集合

如果用的是EF Core,你可以配置值转换器,将Answer集合序列化为JSON字符串存储在单个字段中:

  1. 修正Question类的定义,初始化集合并添加virtual关键字:
public class Question
{
    public int ID { get; set; }
    public string question { get; set; }
    // 初始化集合+添加virtual支持延迟加载
    public virtual ICollection<string> Answer { get; set; } = new List<string>();
    public int CorrectAns { get; set; }
}
  1. 在你继承自DbContext的上下文类中,重写OnModelCreating方法配置转换器:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Question>()
        .Property(q => q.Answer)
        .HasConversion(
            // 存的时候序列化为JSON
            list => System.Text.Json.JsonSerializer.Serialize(list, default),
            // 查的时候反序列化为集合
            json => System.Text.Json.JsonSerializer.Deserialize<ICollection<string>>(json, default)
        );
}
  1. 查询试卷时显式加载关联数据:
// 替换原来的Find方法,用Include+ThenInclude预加载关联的试题和选项
Exam exam = db.Exams
    .Include(e => e.Questions)
    .ThenInclude(q => q.Answer)
    .FirstOrDefault(e => e.ExamID == id);

方案2:EF6/兼容关联表存储的方案

如果用的是EF6,或者希望选项单独存表做查询优化,可以单独创建选项实体类做关联:

// 新增选项实体类
public class AnswerOption
{
    public int Id { get; set; }
    public string Content { get; set; }
    public int QuestionId { get; set; }
    public virtual Question Question { get; set; }
}

// 修改Question类
public class Question
{
    public int ID { get; set; }
    public string question { get; set; }
    public virtual ICollection<AnswerOption> Answer { get; set; } = new List<AnswerOption>();
    public int CorrectAns { get; set; }
}

查询时同样使用Include+ThenInclude预加载关联数据即可。


额外问题修正

你现有Create方法中的判断逻辑存在错误:

if (exam.Time.ToString()!=null  ||exam.Deadline==null)

int类型的Time调用ToString()永远不会返回null,该判断条件永远为真,Deadline会被强制设置为1990-01-01,建议修正为你需要的判断逻辑。


内容的提问来源于stack exchange,提问作者helijacky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:45:04