ASP.NET MVC开发考试系统时Question的Answer列表返回null求解
问题原因说明
C#完全支持列表嵌套的结构,该问题和C#语法无关,是Entity Framework(以下简称EF)的配置、映射和数据加载规则导致的,具体有3个核心问题:
- 基础类型集合没有正确配置映射:EF默认无法直接将
ICollection<string>这类基础类型的集合属性映射到数据库字段,如果你没有做特殊配置,Answer属性的内容在保存试卷时根本不会写入数据库,查询时自然返回null。 - 没有开启延迟加载且属性未初始化:
Question类的Answer属性没有加virtual关键字,EF的延迟加载机制对非virtual属性不生效;同时你没有在类构造函数中初始化集合属性,实例化Question对象时Answer默认就是null。 - 查询时没有显式加载关联数据:你用
db.Exams.Find(id)查询试卷时,默认只会加载Exam本身的字段,关联的Questions下的Answer数据不会主动加载。
解决方案
方案1:EF Core环境下直接用JSON序列化存储基础类型集合
如果用的是EF Core,你可以配置值转换器,将Answer集合序列化为JSON字符串存储在单个字段中:
- 修正
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; } }
- 在你继承自
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) ); }
- 查询试卷时显式加载关联数据:
// 替换原来的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
相关产品推荐
相关产品推荐

