实体框架代码第一:如何为这个简单的推荐方案建模?

时间:2011-10-14 03:51:25

标签: c# entity-framework ef-code-first

我正在尝试模拟看似相对简单的推荐方案。我试图搜索,但我不确定这个名称是什么,我想要创建的关系。

以下是解释:

一名学生可以将另一名学生转介到学校。因此,每个学生都可以推荐许多学生,每个新生只能由一名现有学生推荐。

以下是代码:

// Model
public class Student
{
    public int? ReferralID { get; set; }
    public virtual Referral Referral { get; set; }

    public virtual ICollection<Referral> Referrals { get; set; }
}

public class Referral
{
    public int ReferringStudentID { get; set; }
    public virtual Student ReferringStudent { get; set; }

    public int ReferredStudentID { get; set; }
    public virtual Student ReferredStudent { get; set; }
}

// Context
modelBuilder.Entity<Student>()
    .HasOptional(x => x.Referral)
    .WithMany()
    .HasForeignKey(x => x.ReferralID);

modelBuilder.Entity<Student>()
    .HasMany(x => x.Referrals)
    .WithRequired(x => x.ReferringStudent)
    .HasForeignKey(x => x.ReferringStudentID);

以下是生成的数据库:

Missing a key

问题:

如何让Entity Framework认识到ReferStudentID应该是外键?我尝试使用流畅的API来描述从推荐到学生的关系,但结果是一样的。我做错了吗?

提前致谢! :)

2 个答案:

答案 0 :(得分:1)

问题是EF尝试使用级联删除创建外键。您的推荐表有两个不可空的外键到学生表。如果您删除学生,这将形成多个删除路径。 SQL Server不允许这样做。

使用ReferringStudentID更改外键映射,如下所示

        modelBuilder.Entity<Student>()
            .HasMany(x => x.Referrals)
            .WithRequired(x => x.ReferringStudent)
            .HasForeignKey(x => x.ReferringStudentID)
            .WillCascadeOnDelete(false);

如果您允许删除学生,您需要考虑如何保持参照完整性。

答案 1 :(得分:0)

我承认,我还没有先使用代码。但在我看来,当你只需要一个类时,你正在创建两个类。如果我在SQL DDL中设计这个结构,它看起来像

CREATE TABLE Students
(
    StudentId INT IDENTITY NOT NULL PRIMARY KEY,
    ReferredBy INT NULL REFERENCES Students (StudentId)
)

我不记得是否能够在CREATE TABLE语句中包含自引用外键,或者是否需要单独创建外键约束。

我不确定如何转换为代码优先EF,但我认为你只需要一个而不是两个。