添加对象后,实体框架不会加载导航属性

时间:2015-08-06 13:59:23

标签: c# entity-framework entity-framework-6

我有MVC项目和EF6模型。

enter image description here

启用了LazyLoading。在控制器中,我有以下行动

    public ActionResult AddStage(int projectId, int employeeId)
    {
        using(var context = new TestProjectEntities())
        {
            var project = context.Projects.Find(projectId);
            if (project != null)
            {
                var stage = new Stage() {EmployeeID = employeeId, StageType = 1};
                project.Stages.Add(stage);
                context.Stages.Add(stage);
                context.SaveChanges();
            }

            ListEmployees(project);
        }

        return Redirect("Index");
    }

    private void ListEmployees(Project project)
    {
        var names = new List<string>();
        foreach(var stage in project.Stages)
        {
            if (stage.Employee != null)
            {
                names.Add(stage.Employee.Name);
            }
        }
    }

但是在foreach语句中的ListEmployees方法stage.Employee == null中。 为什么呢?

如果我第二次调用AddStage,那么ListEmployee中的stage.Employee!= null

3 个答案:

答案 0 :(得分:8)

那是因为您只是设置了外键属性(Stage.EmployeeID)而没有设置导航属性(Stage.Employee)。

通常,在调用SaveChanges()之后,EF也会更新导航属性。但是,由于Stage对象是由您手动创建的,因此未对其进行跟踪(使用DynamicProxy),并且您必须明确修复关系:

context.Entry(stage).Reference(c => c.Employee).Load();

另一种方法是获取Employee并使用它而不是设置外键属性:

var employee = context.Employees.Find(employeeId);
var stage = new Stage() { Employee = employee, StageType = 1};

请参阅MSDN

答案 1 :(得分:2)

new Stage()

不要对EF对象执行此操作。您将无法获得可以延迟加载导航属性的正确代理对象。您需要使用类似dbContext.Set<Stage>().Create()

的内容

答案 2 :(得分:0)

我认为在EmployeeID类中使用Stage并使Employee对象具有ID属性可能会令人困惑。我实际上看不到您为Employee分配Stage的位置。我希望看到这样的事情:

var stage = new Stage() {EmployeeID = employeeId, StageType = 1, Employee = stageManager};