Entity framework 实体框架子对象未填充

Entity framework 实体框架子对象未填充,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,我有一个简单的模型,当我在调试器中运行网站时,实体框架无法正确填充该模型 模型很简单: public class Team { /// <summary> /// Constructor required for the EntityFramework to create the object. /// </summary> private Team() { } public Tea

我有一个简单的模型,当我在调试器中运行网站时,实体框架无法正确填充该模型

模型很简单:

public class Team
{
    /// <summary>
    ///     Constructor required for the EntityFramework to create the object.
    /// </summary>
    private Team()
    {            
    }

    public Team(string name, ApplicationUser owner)
    {
        Name = name;
        Owner = owner;
    }

    [Required]
    public int Id { get; private set; }

    [Required]
    public string Name { get; private set; }

    [Required]
    public ApplicationUser Owner { get; private set; }

    [Required]
    public List<TeamMembership> Members { get; set; }
}


public class TeamMembership
{
    /// <summary>
    ///     Constructor for the EntityFramework
    /// </summary>
    private TeamMembership()
    {
    }

    public TeamMembership(ApplicationUser user, MembershipStatus status)
    {
        User = user;
        Status = status;
    }

    [Required]
    public ApplicationUser User { get; private set; }

    [Required]
    public MembershipStatus Status { get; set; }

    [Required]
    public int Id { get; private set; }
}
公共类团队
{
/// 
///EntityFramework创建对象所需的构造函数。
/// 
私人团队()
{            
}
公共团队(字符串名称、应用程序用户所有者)
{
名称=名称;
所有者=所有者;
}
[必需]
public int Id{get;private set;}
[必需]
公共字符串名称{get;private set;}
[必需]
公共应用程序用户所有者{get;private set;}
[必需]
公共列表成员{get;set;}
}
公共班级团队成员
{
/// 
///EntityFramework的构造函数
/// 
私人组员()
{
}
公共团队成员身份(应用程序用户、成员身份状态)
{
用户=用户;
状态=状态;
}
[必需]
公共应用程序用户{get;private set;}
[必需]
公共成员身份状态状态{get;set;}
[必需]
public int Id{get;private set;}
}
其中,
ApplicationUser
是ASP MVC 5成员资格基础结构生成的默认类

当我运行我的测试(Specflow)时,它为每个测试创建一个具有唯一id的新LocalDb数据库,并在该数据库上运行迁移,然后实体框架会正确地填充我的团队和所有者

但是,当我运行网站并尝试与应用程序交互时,我的团队没有完全填充,因为所有者是
null
,而
成员也没有填充。但是在数据库中正确设置了所有者ID,并且查询似乎正常。测试期间执行的查询和应用程序运行期间执行的查询似乎是相同的

为什么会这样?我如何开始调试该问题


我觉得我缺少了一些简单的东西。

您可能需要在查询中添加
.Include()
,这在您的问题中没有显示,但应该如下所示:

var query = context.Teams.Include(x => x.Owner).Include(x => x.Members).Where( ... );
EF将只加载顶级实体,但不会加载它引用的实体,直到需要它们(延迟加载)。如果您还没有处理上下文,那么简单地尝试访问这些导航属性应该会导致它们从数据库加载,但是如果已处理上下文,则不会发生这种情况

.Include()
将通知EF这些导航属性需要与引用实体一起加载


有关懒惰/急切加载以及如何控制的更多详细信息,请参阅。

谢谢Steve。这似乎确实解决了问题。然而,我有点困惑,为什么我的集成测试(在控制器上调用方法)能够工作,并且有完全填充的对象。这是由于上下文生命周期造成的吗?我认为我的测试为测试的生命周期创建了一个上下文,可能是多次控制器方法调用,在IIS SimpleInjector中运行时,每次调用都会创建一个DBContext。但是dbcontext不应该在加载团队和导航所有者/成员之间被释放。如果上下文没有被释放(实体仍然附加到上下文),并且您访问了导航属性,EF应该再次点击数据库以获取该实体。如果释放了上下文,则不会发生这种情况。我将添加一个指向答案的链接以了解更多信息。实体是否仍会附加到上下文,除非它已显式分离?在C#6中,您现在可以使用
nameof
,以获得更大的类型安全性。例如,
.Include(nameof(Team.Owner))
。或者如果您使用的是早期的EntityFramwork版本,例如V4
var query=context.Teams.Include(“所有者”).Include(“成员”)。其中(…)