多重inheritance(可能是抽象类?)C#entity framework

最近几周,我一直致力于使用Visual Studio 2015在c#上基于Entity Framework 6(Code-First)开发数据库。

我目前正在研究inheritance提供的所有选项。 此时并遵循数据库的标准,我应该使用主键实现多重inheritance。 这意味着什么? 这意味着我应该实现一个inheritance自另一个类的类,并拥有自己的PK来识别他与父类不同的类。 此时我可以用TPC实现它,使父类抽象而不是在父类上定义任何PK。 这是此时代码的示例(这有效,我已对其进行了测试)

public abstract class Person { public string Name { get; set; } public string LastName { get; set; } } [Table("Students")] public class Student : Person { [Key]public int Id_student { get; set; } public string code_s { get; set; } public virtual ICollection courses { get; set; } } 

然后我应该按照标准来构建我的数据库,这要求我实现另一个inheritance,将Student作为Parent并创建另一个inheritance自Student的类。 我的第一个也是愚蠢的想法是让它像写一样简单

 ChildOfChild : Student 

但显然它没有用。

然后我想到了make Student类Abstract的可能性,但是当我声明Student类Abstract时,它没有让我实例化它并播种表。 我不确定是否有任何其他方法可以使用抽象类或任何其他方法来开发它。 如果您不理解我正在尝试解决的问题,那么我希望拥有并运行的代码示例。

  public abstract class Person { public string Name { get; set; } public string LastName { get; set; } } [Table("Students")] public class Student : Person { [Key]public int Id_student { get; set; } public string code_s { get; set; } public virtual ICollection courses { get; set; } } [Table("ExchangeStudent")] public class ExchangeStudent : Student { [Key]public int Id_exchange { get; set; } public string HomeUniversity {get; set;} } 

根据我的理解,您需要两个表,其中两个表都有自己的主键和外键来定义一对一的关系。 在C#代码中,您希望这些表具有inheritance关系。

我可以看到你使用Entity Framework执行此操作的唯一方法是分割您的需求。 首先创建表示所需表结构的数据库模型。

 namespace DAO { public abstract class Person { public string Name { get; set; } } public class Student { public int StudentId { get; set; } public string Nickname { get; set; } } //Use navigation property rather than inheritance to define the relationship public class ExchangeStudent { public int ExchangeStudentId { get; set; } public string HomeUniversity { get; set; } public virtual Student Student { get; set; } } } 

这给了我以下代码:

  public override void Up() { CreateTable( "dbo.ExchangeStudent", c => new { ExchangeStudentId = c.Int(nullable: false, identity: true), HomeUniversity = c.String(), Student_StudentId = c.Int(), }) .PrimaryKey(t => t.ExchangeStudentId) .ForeignKey("dbo.Student", t => t.Student_StudentId) .Index(t => t.Student_StudentId); CreateTable( "dbo.Student", c => new { StudentId = c.Int(nullable: false, identity: true), Nickname = c.String(), Name = c.String(), }) .PrimaryKey(t => t.StudentId); } 

现在,如果需要在Student和ExchangeStudent之间建立inheritance关系,则可以创建要在不同命名空间中定义的新对象

 namespace BusinessObject { public abstract class Person { public string Name { get; set; } } public class Student { public int StudentId { get; set; } public string Nickname { get; set; } } //ExchangeStudent derives from Student public class ExchangeStudent : Student { public int ExchangeStudentId { get; set; } public string HomeUniversity { get; set; } } } 

然后你只需要创建一个映射两个对象的类。 还有第三方库也可以为您执行此操作。

你不能有两个主键。 StudentId_student定义为主键,然后在ExchangeStudent Id_exchange定义为主键。 我将在Person实现属性’Id’并删除Id_studentId_exchange属性。

  public abstract class Student : Person { [Key]public int Id_student { get; set; } } public class LocalStudent : Student{ } public class ExchangeStudent : Student { public string HomeUniversity {get; set;} } 

但我会想到类似的东西

 public class Student : Person { [Key]public int Id_student { get; set; } public string code_s { get; set; } public virtual ICollection courses { get; set; } public ExchangeInfo ExchangeInfo{get;set;} } public class ExchangeInfo : Student { [Key]public int Id_exchange { get; set; } public Student Student{get;set;} public string HomeUniversity {get; set;} } 

HomeUniversity听起来像学生的属性吗? 使用单个学生表更方便,而不是从2个表中选择2个,找出谁真正在监听cources以及如何创建表格的链接,如课程到两个表Student和ExchangeStudent?

会有没有Id吗? 如果没有,请为Person提供Id属性。 在您的流畅API中定义您对TPC进行建模,即此ID是您的学生以及交换学生的主要关键。

 public class Person { public int Id {get; set; public string Name { get; set; } public string LastName { get; set; } } public class Student : Person { // the primary key is in the base class public string code_s { get; set; } public virtual ICollection courses { get; set; } } public class ExchangeStudent : Student { // the primary key is in one of the base classes public string HomeUniversity {get; set;} } 

您的DbContext配置此链接中的 TPC

 class MyDbContext : DbContext { public DbSet Students {get; set;} public DbSet ExchangeStudents {get; set;} protected override OnModelCreating(...) { // configure Student and ExcahngeStudent as TPC, // if needed define primary key modelBuilder.Entity() .HasKey(student => student.Id) .Map(m => { m.MapInheritedProperties(); m.ToTable("Students"); }); modelBuilder.Entity() .HasKey(student => student.Id) .Map(m => { m.MapInheritedProperties(); m.ToTable("ExchangeStudents"); }); } 

我不确定是否需要HasKey 。 因为主键遵循命名约定 ,所以可能不需要它。

在属性的使用之上使用流畅的API的优点是,它允许您在不同的数据库模型中使用相同的类和查询,只需指定不同的DbContext即可。