具有相同类型的导航属性集合的EF6 Code First Entity - 如何告诉EF这是什么关系?

时间:2014-01-20 15:02:57

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

我不太了解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代码。希望有人能清除我头脑中的云彩。

ENTITY

[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等级的跛脚等级。< / p>

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

请帮助我理解协会,这样我就可以开始工作。欣赏它。我的第一篇SO帖子请你温柔。

1 个答案:

答案 0 :(得分:0)

这是一种(自我引用)多对多关系:一个年级可以有许多合格的成绩,一个成绩可以是许多其他成绩的合格成绩。你可以把它想象成好像 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");
    });

您问题中的最后一个代码段现在可以使用此映射,并准确提供您期望的结果。