EF 6 codde first - 一对多映射 - ICollection始终为null

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF 6 codde first - 一对多映射 - ICollection始终为null相关的知识,希望对你有一定的参考价值。

我知道这个问题之前曾多次被问过,但我有一个奇怪的行为在我身边,我无法得到任何解决方案。

我正在使用EF6和代码构建一个.Net应用程序。我将我的类定义如下(这些是示例类,但我有完全相同的结构):

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int RefId { get; set; }

    public int GradeId { get; set; }
    public Grade Grade { get; set; }
}

public class Grade
{
    private string _name;

    public int GradeId { get; set; }
    public string GradeName { get; set; }

    public ICollection<Student> Students { get; set; }
}

我知道默认情况下启用延迟加载超过ef 4,并且主要工作的解决方案是从实体中删除虚拟关键字(非虚拟属性)。

在我的例子中,我想在Grade类的getter方法中设置一些自定义代码,但ICollection<Student> Students始终为null。

例如:

public string GradeName
{
    get
    {
        _name = Students.FirstOrDefault(s => s.GradeId == GradeId &&
                              s.RefId == 2).Name;

        if (string.IsNullOrWhiteSpace(_name))
        {
            _name = Name;
        }

        return _name;
    }

    set => _name = value;
}

我尝试了一切,没有任何帮助。如果你可以帮我解决这个问题,那将是很棒的,谢谢!

答案

你误解了懒惰与急切加载的效果。见here

将集合标记为虚拟意味着它被推迟。删除它不会填充集合,您仍然需要包括:

var studentWithGrade = context.Students
            .Include(s => s.Grade)
            .FirstOrDefault(s => s.GradeId == GradeId && s.RefId == 2);

或学生收藏的成绩:

var gradeWithStudents = context.Grade
            .Include(g => g.Students)
            .ToList();

更多包括组合here

另一答案

您应该在构造函数中初始化学生,因为它是该类的责任:

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }

    public ICollection<Student> Students { get; set; }

    public Grade ()
    {
        Students = new Collection<Student>();
    }
}

以上是关于EF 6 codde first - 一对多映射 - ICollection始终为null的主要内容,如果未能解决你的问题,请参考以下文章

EF 6.1 Code First 中与不同主键的一对一关系

EF Code First 学习笔记:关系

EF Code First 导航属性 与外键

EF Code First 导航属性 与外键

EF Core开发模式之Code First

EF Code First关系规则及配置