【问题标题】:EF6 Code First Entity with navigation property collection of same type - how do I tell EF what the relationship is?具有相同类型导航属性集合的 EF6 代码优先实体 - 我如何告诉 EF 关系是什么?
【发布时间】:2014-01-20 15:02:57
【问题描述】:

我不太了解 EF,所以在我试图克服我的无知和困惑时,请多多包涵。我有一个限制,我不能改变数据库结构。

TBLGRADES

GRADEID GUID  (PK)                   | GRADETITLE VARCHAR
--------------------------------------------------------------
882349d4-2564-4160-a034-2a5116dec389 | Cool Grade

59539804-5c47-46ac-873d-65b33ce6ac94 | Not so cool grade

b00d6cdd-3273-4f83-8d18-0c9e9a3e1562 | Lame Grade

TBLGRADESRELATIONSHIPS

GRADEID GUID  (FK)                    | ELIGIBLEGRADEID GUID (FK)
----------------------------------------------------------------------------
882349d4-2564-4160-a034-2a5116dec389  | 59539804-5c47-46ac-873d-65b33ce6ac94

882349d4-2564-4160-a034-2a5116dec389  | b00d6cdd-3273-4f83-8d18-0c9e9a3e1562

我希望首先使用 EF 代码来表示它,但我正在苦苦挣扎,因为我不了解 EF 的工作原理,但我可以使用 EF 代码生成来让它工作。如果我不能首先使用代码让它工作,那么我只需要满足于 EF 代码生成。希望有人能清除我脑海中的乌云。

实体

[Table("TBLGRADES")]
public class Grade
{
    public GUID GradeId { get; set; }
    public string GradeTitle { get; set; }
    public virtual ICollection<Grade> EligibleGrades { get; set; }
}

我想要一个代表 Cool Grade 的 Grade 实体实例,拥有一组 Grade 实体 (EligibleGrades)(计数:2),其中包含 1 个不太酷的成绩实例和 1 个蹩脚成绩实例,根据 TBLGRADESRELATIONSHIPS。

var grade = rep.GetGradeByID(Guid.Parse("882349d4-2564-4160-a034-2a5116dec389"));
grade.EligibleGrades[0] //Not so cool grade
grade.EligibleGrades[1] //lame grade

请帮助我了解关联,以便我可以正常工作。欣赏它。我的第一个 SO 帖子,所以请温柔。

【问题讨论】:

    标签: c# entity-framework entity-framework-6 relationships navigation-properties


    【解决方案1】:

    这是一种(自引用)多对多关系:一个成绩可以有多个合格成绩,一个成绩可以是许多其他成绩的合格成绩。你可以把它想好像Grade实体有另一个(隐藏的)集合,比如:

    public class Grade
    {
        public GUID GradeId { get; set; }
        public string GradeTitle { get; set; }
        public virtual ICollection<Grade> EligibleGrades { get; set; }
        public virtual ICollection<Grade> GradesThisIsAnEligibleGradeFor { get; set; }
    }
    

    名字太丑了,我们又把集合删了。但是您仍然必须告诉 EF 关系是多对多的。如果 Code-First 模型发现只看到一个集合,它总是假定 一对多 关系(TBLGRADES 表中不存在的外键)。您必须使用 Fluent API 覆盖默认约定,以便改为创建 多对多 关系:

    modelBuilder.Entity<Grade>()
        .HasMany(g => g.EligibleGrades)
        .WithMany() // <- parameterless because there's no 2nd (inverse) collection
        .Map(m =>
        {
            m.ToTable("TBLGRADESRELATIONSHIPS");
            m.MapLeftKey("GRADEID");
            m.MapRightKey("ELIGIBLEGRADEID");
        });
    

    您问题中的最后一个代码 sn-p 现在应该可以使用此映射并给出您期望的结果。

    【讨论】:

    • 这绝对是完美的!在无参数的 WithMany() 上,我假设我是否应该向上遍历图表以找出当前等级有资格获得哪些等级,我必须在那里进行配置?还是我理解错了?
    • @user3215462:是的,然后你会使用.WithMany(g =&gt; g.GradesThisIsAnEligibleGradeFor)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    相关资源
    最近更新 更多