简体   繁体   English

EF 6编码优先-一对多映射-ICollection始终为null

[英]EF 6 codde first - One To Many Mapping - ICollection always null

I know this question was asked many times before, but I have a strange behavior at my side and I couldn't get any solution. 我知道这个问题以前曾被问过很多次,但我的行为举止很奇怪,无法解决。

I'm building a .Net application with EF6 and code first. 我正在使用EF6构建一个.Net应用程序,并首先编写代码。 I defined my classes as follows (these are example classes but I have exactly the same structure): 我将类定义如下(这些是示例类,但结构完全相同):

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; }
}

I understand that lazy loading is enabled by default beyond ef 4, and the solution that mostly work is to remove the virtual keyword from the entities (non-virtual properties). 我了解默认情况下,ef 4之后会默认启用惰性加载,而最有效的解决方案是从实体(非虚拟属性)中删除virtual关键字。

In my case, I want to set some custom code in the getter method of the Grade class, but ICollection<Student> Students is always null. 就我而言,我想在Grade类的getter方法中设置一些自定义代码,但是ICollection<Student> Students始终为null。

For example: 例如:

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;
}

I tried everything possible, nothing helped. 我尽一切可能,没有任何帮助。 It will be great if you can help me solve this issue, thanks! 如果您能帮助我解决这个问题,那就太好了,谢谢!

You are misunderstanding how lazy vs eager loading works. 您误会了懒惰加载和渴望加载的工作方式。 See here . 这里

Marking the collection virtual just means it is deferred. 将收藏集标记为虚拟只是意味着将其推迟。 Removing it does not populate the collection, you still need the Include: 删除它不会填充集合,您仍然需要包括:

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

or the grade with the student collection: 或学生系列的成绩:

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

More include combinations here . 更多包括这里的组合。

You should initialize students in the constructor as it's responsibility of the class: 您应该在构造函数中初始化学生,因为这是班级的职责:

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>();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM