Search code examples
c#visual-studioentity-frameworkinheritancecode-first

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


The last weeks I have been working on the development of a database based on Entity Framework 6 (Code-First) on c# using Visual Studio 2015.

I'm currently working on all the options that inheritance offers to work with. At this point and following the standards of a database I should implement multiple inheritance with Primary Key. What this means? This means that I should implement a class that inherits from another class and have his own PK for identify him different from the parent class. At this point I could implement it with TPC, making the parent class abstract and not defining any PK on the parent. This is a sample of the code at this point (this works and I have tested it)

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

    }

Then the standard I should follow to build my database requires me to implement another inheritance taking Student as the Parent and creating another class that inherits from Student. The first and stupid idea I had was to make it as simple as write

ChildOfChild : Student

But obviously it didn't work.

Then it come to my mind the possibility of make Student class Abstract, but when I declared the Student class Abstract it didn't let me instantiate it and seed the table. I'm not sure if there is any other way to do this, using abstract class or any other method that could be useful to develop this. If you didn't understand the problem I'm trying to solve this is the sample of code that I would like to have and works.

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

    }

Solution

  • From my understanding you want two tables where both with their own primary keys and a foreign key to define a one to one relationship. In your C# code you want these tables to have an inheritance relationship.

    The only way I can see you doing this with Entity Framework is to split your requirements. Firstly create the Database models that represent the table structure you want.

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

    This gave me the following code:

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

    Now if you need to have a inheritance relationship between Student and ExchangeStudent you can create new objects to define in a different namespace

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

    Then you just need to create a class that maps the two objects. There are 3rd party libraries that can do this for you as well.