C# 实体框架代码优先:如何对这个简单的引用场景建模?
我试图模拟一个相对简单的推荐场景。我尝试过搜索,但我不确定我想要建立的那种关系的名字是什么 解释如下:C# 实体框架代码优先:如何对这个简单的引用场景建模?,c#,entity-framework,ef-code-first,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; } }
// 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);
一个学生可以把另一个学生介绍给学校。因此,每个学生可以推荐许多学生,而每个新生只能由一名现有学生推荐
代码如下:
// 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);
//模型
公立班学生
{
公共int?ReferralID{get;set;}
公共虚拟引用{get;set;}
公共虚拟ICollection引用{get;set;}
}
公共类转介
{
public int refereringstudentid{get;set;}
公共虚拟学生引用学生{get;set;}
public int referedStudentId{get;set;}
公共虚拟学生referedStudent{get;set;}
}
//上下文
modelBuilder.Entity()
.has可选(x=>x.reference)
.有很多
.HasForeignKey(x=>x.ReferralID);
modelBuilder.Entity()
.HasMany(x=>x.Referrals)
.WithRequired(x=>x.ReferringStudent)
.HasForeignKey(x=>x.refereringstudentid);
这是结果数据库:
// 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);
问题:
// 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);
我该怎么做才能让实体框架认识到ReferringStudentID应该是外键?我试着用fluent API来描述从推荐到学生的关系,但结果是一样的。我做错什么了吗
提前感谢!:) 无可否认,我没有先使用过代码。不过,在我看来,您创建的是两个类,而您只需要一个。如果我在SQLDDL中设计这个结构,它看起来会像
CREATE TABLE Students
(
StudentId INT IDENTITY NOT NULL PRIMARY KEY,
ReferredBy INT NULL REFERENCES Students (StudentId)
)
我不记得是否能够在CREATETABLE语句中包含自引用外键,或者是否需要单独创建外键约束
我不确定如何准确地转换为code first EF,但我认为您只需要一个类,而不是两个。问题是EF尝试使用级联删除创建外键。您的参考表有两个不可为空的学生表外键。如果删除学生,将形成多个删除路径。SQL Server不允许这样做 使用
refereringstudentid
更改外键映射,如下所示
modelBuilder.Entity<Student>()
.HasMany(x => x.Referrals)
.WithRequired(x => x.ReferringStudent)
.HasForeignKey(x => x.ReferringStudentID)
.WillCascadeOnDelete(false);
modelBuilder.Entity()
.HasMany(x=>x.Referrals)
.WithRequired(x=>x.ReferringStudent)
.HasForeignKey(x=>x.ReferringStudentID)
.WillCascadeOnDelete(假);
如果允许删除学生,您需要考虑如何保持参考完整性。谢谢您的回复。这可能会起作用,但是转介类还有一些属性仅适用于转介而不适用于学生。我不想把它们放在学生课上,因为它们真的不属于那里。我想说,这是一个很好的数据库设计,只在一个表中有引用,它为关于(和)引用的强大信息腾出空间,你甚至不需要查找用户表(除非你需要特定于用户的数据)。我认为外键学生只需要是独一无二的,所以它只能存在一次。这意味着一个学生被推荐,当它被推荐时。非常感谢!我太习惯于EF警告我关于多条删除路径,我甚至没有考虑过它。