Implementation inheritance of MVC5 Entity Framework Learning

Source: Internet
Author: User

Implementation inheritance of MVC5 Entity Framework Learning

You have learned how to handle concurrency exceptions. In this section, you will learn how to implement inheritance.

In object-oriented programming, you can use inheritance to reuse code. Next, you will modify the Instructor and Student classes so that they can be derived from the Person base class. This base class contains the attributes common to the ucuctor and student, such as LastName. You do not need to add or modify any WEB pages, but you need to modify some code, which will be automatically reflected in the database.

Ing to database options

The Instructor and Student classes in the School data model have the same attributes:

Suppose you want to reduce redundant code by sharing the attributes of the uctor and Student entities, or you want to write a service program to format the name without worrying about whether the name is from the uctor or student. You can create a Person base class that contains these common attributes, and then let the aggreguctor and Student inherit the base class, as shown in:

 

In databases, this inheritance structure can have multiple forms. You can create a Person database table that contains student and uctor information at the same time. Some columns in this table are only applicable to instructor (HireDate), and some are only applicable to student (EnrollmentDate ), in addition, it can be applied to uctor or student (LastName, FirstName ). Generally, you should create an ID column to specify the types represented by each row. For example, you can use an uctor to represent instructors and Student to represent students.

This mode of generating an Object Inheritance structure from a single database table is called a table (table-per-hierarchy) hierarchy.

Another alternative is to make the database look more like an inheritance structure. For example, you can only include the name field in the Person table and the date field in the uctor and Student tables respectively.

This mode creates a database table for each object class is called a table per type inheritance for each type.

Another option is to map all non-abstract types to individual tables. All attributes of a Class, including inherited attributes, are mapped to the columns in the corresponding Table. This mode is called the inheritance of a Table (Table-per-Concrete Class) for each specific Class. If you implement TPC inheritance for the Person, Student, and uctor classes, the Student and uctor tables are no different from the previous ones.

In Entity Framework, the TPC and TPH inheritance modes have better performance than the TPT inheritance modes, because the TPT mode may produce complex connection queries.

This section describes how to implement TPH inheritance. TPH inheritance is the default inheritance mode of Entity Framework, so you need to create a Person class, modify the policuctor and Student classes to make them derived from the Person class, add a new class to DbContext and create a migration.

Create Person class

Open the Models folder, create the Person. cs class, and replace it with the following method:

 

using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace ContosoUniversity.Models{    public abstract class Person    {        public int ID { get; set; }        [Required]        [StringLength(50)]        [Display(Name = Last Name)]        public string LastName { get; set; }        [Required]        [StringLength(50, ErrorMessage = First name cannot be longer than 50 characters.)]        [Column(FirstName)]        [Display(Name = First Name)]        public string FirstMidName { get; set; }        [Display(Name = Full Name)]        public string FullName        {            get            {                return LastName + ,  + FirstMidName;            }        }    }}
Enable Student and policuctor class to inherit the Person class, enable Instructor. cs, enable the policuctor class to inherit the Person class, and delete the key and name fields.

 

 

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace ContosoUniversity.Models{    public class Instructor : Person    {        [DataType(DataType.Date)]        [DisplayFormat(DataFormatString = {0:yyyy-MM-dd}, ApplyFormatInEditMode = true)]        [Display(Name = Hire Date)]        public DateTime HireDate { get; set; }        public virtual ICollection
 
   Courses { get; set; }        public virtual OfficeAssignment OfficeAssignment { get; set; }    }}
 
Open Student. cs and make the same changes.

 

 

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace ContosoUniversity.Models{    public class Student : Person    {        [DataType(DataType.Date)]        [DisplayFormat(DataFormatString = {0:yyyy-MM-dd}, ApplyFormatInEditMode = true)]        [Display(Name = Enrollment Date)]        public DateTime EnrollmentDate { get; set; }        public virtual ICollection
 
   Enrollments { get; set; }    }}
 
Add the Person object type to the model. Open SchoolContext. cs and add the DbSet attribute to the Person object type.

 

 

public DbSet
 
   People { get; set; }
 

 

This is the modification required to inherit a table in each hierarchy of Entity Framework configuration. later you will see a new Person data table when the database is updated.

Create and update the migration File

In the Package Manager Console (PMC) window, enter the following command:

 

Add-Migration Inheritance
Then run the Update-Database command, which will fail because the migration program does not know how to process the existing data. The error message is as follows:

 

 

Could not drop object 'dbo.Instructor' because it is referenced by a FOREIGN KEY constraint.

 

Open Migrations _ Inheritance. cs, modify the Up Method

 

public override void Up(){    // Drop foreign keys and indexes that point to tables we're going to drop.    DropForeignKey(dbo.Enrollment, StudentID, dbo.Student);    DropIndex(dbo.Enrollment, new[] { StudentID });    RenameTable(name: dbo.Instructor, newName: Person);    AddColumn(dbo.Person, EnrollmentDate, c => c.DateTime());    AddColumn(dbo.Person, Discriminator, c => c.String(nullable: false, maxLength: 128, defaultValue: Instructor));    AlterColumn(dbo.Person, HireDate, c => c.DateTime());    AddColumn(dbo.Person, OldId, c => c.Int(nullable: true));    // Copy existing Student data into new Person table.    Sql(INSERT INTO dbo.Person (LastName, FirstName, HireDate, EnrollmentDate, Discriminator, OldId) SELECT LastName, FirstName, null AS HireDate, EnrollmentDate, 'Student' AS Discriminator, ID AS OldId FROM dbo.Student);    // Fix up existing relationships to match new PK's.    Sql(UPDATE dbo.Enrollment SET StudentId = (SELECT ID FROM dbo.Person WHERE OldId = Enrollment.StudentId AND Discriminator = 'Student'));    // Remove temporary key    DropColumn(dbo.Person, OldId);    DropTable(dbo.Student);    // Re-create foreign keys and indexes pointing to new table.    AddForeignKey(dbo.Enrollment, StudentID, dbo.Person, ID, cascadeDelete: true);    CreateIndex(dbo.Enrollment, StudentID);}

 

The above code executes the following database update tasks:

Removed the foreign key constraints and indexes of Student database tables.

 

Rename the policuctor table to Person and make the following changes to store Student data.
Added an identifier column for Student's EnrollmentDate to indicate whether the column is a student or uctor because student does not have hire date, therefore, you can set HireDate to add a temporary field for nullable to update the foreign key pointing to student and copy the data in the Student table to the Person table, in this way, Student can get a new primary key value, fix the foreign key value pointing to student, and recreate the foreign key constraints and indexes so that they point to the Person table.

 

If you have used GUID instead of integer as the primary key type, the primary key value of student will not be changed, and the above steps can be omitted.

Run the update-database command again.

In the production environment, you need to modify the Down method so that you do not have to roll back to the previous database version. In this example, the Down method is not required.

Note: When you migrate data or change the architecture, you may encounter other errors. If you encounter a migration error but cannot solve it, you can modify the Web. in this tutorial, the simplest way is to rename the Web. config. Change the database name to ContosoUniversity2 as follows

 

You can use a newly created database that does not have any data for Migration. update-database should be successfully executed. 

 

Test

Run the project and try to access different pages. Everything works properly.

Open Server Explorer and expand Data ConnectionsSchoolContext Tables. You can see that the Student and uctor Tables have been replaced by the Person table. Open the Person table, and you can see that the table has all columns of the Student and uctor Tables.

On the Person Table, right-click Show Table Data to view the discriminator column.

Below is the new School database architecture

Deploy to Windows Azure

1. in Visual Studio, right-click Solution Explorer and choose Publish

2. Click Publish.

The site is automatically opened in the default browser.

3. Verify if the application works properly

When you run the project and access the database for the first time, Entity Framework automatically runs the Up method in all migration tasks to ensure that the database architecture is consistent with the current data model.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.