簡體   English   中英

多重繼承(也許是抽象類?)C#實體框架

[英]Multiple Inheritance (maybe Abstract class?) C# Entity Framework

最近幾周,我一直在使用Visual Studio 2015在c#上基於Entity Framework 6(代碼優先)開發數據庫。

我目前正在處理繼承提供的所有選項。 在這一點上,並按照數據庫的標准,我應該使用主鍵實現多重繼承。 這是什么意思 這意味着我應該實現一個從另一個類繼承的類,並具有自己的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<Course> courses { get; set; }

    }

然后,我應該遵循的建立數據庫的標准要求我實現另一個繼承,以Student為父級,並創建另一個繼承自Student的類。 我第一個愚蠢的想法是使其變得像編寫一樣簡單

ChildOfChild : Student

但是顯然它沒有用。

然后我想到了使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<Course> courses { get; set; }

    }

    [Table("ExchangeStudent")]
    public class ExchangeStudent : Student
    {

        [Key]public int Id_exchange { 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<Course> 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個選擇相比,將更加舒適,以找出誰真正在聆聽課程,以及如何為課程表(如課程表)創建兩個表Student和ExchangeStudent的鏈接?

會不會有什么Person不具有的Id 如果沒有,給予PersonId屬性。 定義你的流利的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<Course> 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<Student> Students {get; set;}
    public DbSet<ExchangeStudent> ExchangeStudents {get; set;}

    protected override OnModelCreating(...)
    {   // configure Student and ExcahngeStudent as TPC,
        // if needed define primary key
        modelBuilder.Entity<Student>()
        .HasKey(student => student.Id)
        .Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Students");
        });

        modelBuilder.Entity<ExchangeStudent>()
        .HasKey(student => student.Id)
        .Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("ExchangeStudents");
        });
    }

我不知道如果HasKey是必要的。 因為主鍵下面的命名約定 ,這可能是不需要的。

使用屬性的使用上面流暢API的優勢在於,它給你的自由只是通過指定不同的DbContext使用相同的類和查詢在不同的數據庫模型。

根據我的理解,您希望兩個表都具有各自的主鍵和一個外鍵來定義一對一關系。 在您的C#代碼中,您希望這些表具有繼承關系。

我看到您使用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之間建立繼承關系,則可以創建新對象以在其他命名空間中定義

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; }
    }
}

然后,您只需要創建一個映射兩個對象的類。 也有第三方庫可以為您執行此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM