我正在尝试模拟看似相对简单的推荐方案。我试图搜索,但我不确定这个名称是什么,我想要创建的关系。
以下是解释:
一名学生可以将另一名学生转介到学校。因此,每个学生都可以推荐许多学生,每个新生只能由一名现有学生推荐。
以下是代码:
// 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);
以下是生成的数据库:
问题:
如何让Entity Framework认识到ReferStudentID应该是外键?我尝试使用流畅的API来描述从推荐到学生的关系,但结果是一样的。我做错了吗?
提前致谢! :)
答案 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,但我认为你只需要一个而不是两个。