未加载可选导航属性

本文关键字:导航 属性 加载 | 更新日期: 2023-09-27 18:13:45

我不明白为什么实体框架(4.1,代码优先)没有实现可选的导航属性。

少:

public class PlanMember {
    public Int64 Id { get; set; }
    public String FirstName { get; set; }
    public virtual SystemUser CaseManager { get; set; }
    public String LastName { get; set; }
    public virtual PlanMemberStatus Status { get; set; }
}
public class SystemUser {
    public String EMail { get; set; }
    public String FirstName { get; set; }
    public String Id { get; set; }
    public String LastName { get; set; }
}
public class PlanMemberStatus {
    public Int32 Id { get; set; }
    public String Code { get; set; }
}

配置类:

public class ForPlanMemberEntities:EntityTypeConfiguration<PlanMember> {
    public ForPlanMemberEntities(String schemaName) {
        this.HasOptional(e => e.CaseManager)
            .WithMany()
            .Map(m => m.MapKey("CaseManagerID"));
        this.HasRequired(e => e.Status)
            .WithMany()
            .Map(m => m.MapKey("StatusID"));
        this.ToTable("PlanMember", schemaName);
    }
}
public class ForSystemUserEntities:EntityTypeConfiguration<SystemUser> {
    public ForSystemUserEntities(String schemaName) {
        this.ToTable("SystemUser", schemaName);
    }
}
public class ForPlanMemberStatusEntities:EntityTypeConfiguration<PlanMemberStatus> {
    public ForPlanMemberStatusEntities(String schemaName) {
        this.ToTable("PlanMemberStatus", schemaName);
    }
}

背景:

public class Context:DbContext {
    public DbSet<PlanMember> PlanMemberDbSet { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        var schemaName = Properties.Settings.Default.SchemaName;
        modelBuilder.Configurations
            .Add(new Configuration.ForPlanMemberEntities(schemaName))
            .Add(new Configuration.ForPlanMemberStatusEntities(schemaName))
            .Add(new Configuration.ForSystemUserEntities(schemaName))
            ;
    }
}

基于该配置,如果我运行如下查询,它将不会填充CaseManager属性。PlanMemberStatus属性加载正常

var test = (from member in PlanMemberDbSet
            where member.CaseManager != null
            select member).First();
var cm = test.CaseManager;

在我的例子中,cm总是null,尽管事实上-从逻辑上讲-它应该是不可能的。任何想法吗?

EDIT -如果我做PlanMemberDbSet.Include("CaseManager"),那么它按预期工作。为什么这是必要的?在其他情况下,我不需要这样做。

未加载可选导航属性

我的猜测是PlanMember表中的CaseManagerID外键列值与SystemUser表中的Id主键列值不同-不同于。net,但不适用SQL Server(使用标准排序系统),例如不同的大小写:"a"在CaseManagerID中,但"a"在Id中。

查询!= null(在SQL中转换为IS NOT NULL)工作,因此您确实只得到在数据库中分配了SystemUserPlanMember实体。此外,CaseManager的查询(由延迟加载触发)在数据库中正确执行(INNER JOIN)并传输到客户端。甚至物体物质化也起作用了(上下文中有两个物体)。但是EF无法将加载的PlanMember与加载的CaseManager联系起来,因为键不相同(例如,关于大写/小写字母)。因此,你的导航属性是null

这不会发生在Status导航属性中,因为键是Int32

这个问题看起来与这个密切相关:EF 4.1查找/更新中的代码优先错误。有解决方案吗?应该报告吗?