Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架代码优先:如何对这个简单的引用场景建模?_C#_Entity Framework_Ef Code First - Fatal编程技术网

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警告我关于多条删除路径,我甚至没有考虑过它。