Entity Framework 6 Recipes Chinese translation series (9), entityframework

Source: Internet
Author: User

Entity Framework 6 Recipes Chinese translation series (9), entityframework

For the original intention of translation and why I chose Entity Framework 6 Recipes, see the beginning of this series.

2-10 Table per Hierarchy Inheritance Modeling

Problem

You have such a database table with a type or validation column. It can determine what data in a row represents in your application. You want to use table per hierarchy (TPH) to inherit ing modeling.

 

Solution

Let's assume that you have a table between 2 and 20 (the graph used by the author is not the same as the actual description, for example, an entity model graph ), the Employee table contains the rows of hourly employees and salaried employees. The column EmployeeType is used as the identification column to identify the rows of the two employee types. When the value of EmployeType is 1, this line represents a full-time employee (salaried or full-time employee). When the value is 2, this line of code is a hour worker (hourly employee ).

Figure 2-20 A Table named Employee that contains hourly employees and salaried employees

Follow these steps to use TPH for table-based Employee Modeling:

1. Create a context object EF6RecipesContext inherited from DbContext in your project;

2. Use Code List 2-21 to create an abstract POCO entity Employee;

Code List 2-21. Create an abstract POCO entity Employee

1     [Table("Employee", Schema = "Chapter2")]2     public abstract class Employee {3         [Key]4         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]5         public int EmployeeId { get; protected set; }6         public string FirstName { get; set; }7         public string LastName { get; set; }8     }

3. Use Code List 2-22 to create a POCO entity class FullTimeEmployee that inherits to Emplyee.

Code List 2-22.Create a POCO object class FullTimeEmployee

1 public class FullTimeEmployee : Employee2 {3 public decimal? Salary { get; set; }4 }

4. Use Code List 2-23 to create a POCO entity class HourlyEmployee that inherits to Emplyee.

Code List 2-23.Create a POCO object class HourlyEmployee

1  public class HourlyEmployee : Employee {2             public decimal? Wage { get; set; }3         }

5. Add a DbSet <Employee> attribute in the context.

6. Rewrite the OnModelCreating method in the context to map your specific employee type to the EmployeeType identification column in the method. As shown in code list 2-24.

     Code List 2-24.Override the OnModelCreating method in the context

        protected override void OnModelCreating(DbModelBuilder modelBuilder) {            base.OnModelCreating(modelBuilder);            modelBuilder.Entity<Employee>()            .Map<FullTimeEmployee>(m => m.Requires("EmployeeType").HasValue(1))            .Map<HourlyEmployee>(m => m.Requires("EmployeeType").HasValue(2));        }

 

Note: Non-shared attributes (such as Salary and Wage) must be empty.

 

Principle

In the inheritance ing of table per hierarchy (TPH), a separate table is used to represent the entire inheritance hierarchy. Unlike TPT, TPH combines the base class and derived class into the rows of the same table at the same time. They are distinguished by the identification column. In our example, the validation column is EmployeeType.

In TPH, we set the ing condition in the object configuration to indicate that the values of the validation columns map the table to different derived types. Let's make the base class abstract type. By setting it as an abstract type, I don't need to provide a ing condition, because an abstract object will not be created. We will never have an instance of the Employee entity. We do not need to implement an EmployeeType attribute in the Employee object. Columns are not used as ing conditions. Generally, they are mapped to an attribute.

Code List 2-25 shows how to insert and retrieve data from a model.

Code List 2-25Insert and retrieve data in our TPH Model

 1  using (var context = new EF6RecipesContext()) { 2                 var fte = new FullTimeEmployee { 3                     FirstName = "Jane", 4                     LastName = "Doe", 5                     Salary = 71500M 6                 }; 7                 context.Employees.Add(fte); 8                 fte = new FullTimeEmployee { 9                     FirstName = "John",10                     LastName = "Smith",11                     Salary = 62500M12                 };13                 context.Employees.Add(fte);14                 var hourly = new HourlyEmployee {15                     FirstName = "Tom",16                     LastName = "Jones",17                     Wage = 8.75M18                 };19                 context.Employees.Add(hourly);20                 context.SaveChanges();21             }22             using (var context = new EF6RecipesContext()) {23                 Console.WriteLine("--- All Employees ---");24                 foreach (var emp in context.Employees) {25                     bool fullTime = emp is HourlyEmployee ? false : true;26                     Console.WriteLine("{0} {1} ({2})", emp.FirstName, emp.LastName,27                     fullTime ? "Full Time" : "Hourly");28                 }29                 Console.WriteLine("--- Full Time ---");30                 foreach (var fte in context.Employees.OfType<FullTimeEmployee>()) {31                     Console.WriteLine("{0} {1}", fte.FirstName, fte.LastName);32                 }33                 Console.WriteLine("--- Hourly ---");34                 foreach (var hourly in context.Employees.OfType<HourlyEmployee>()) {35                     Console.WriteLine("{0} {1}", hourly.FirstName, hourly.LastName);36                 }37             }

 

The output of the code list is:

--- All Employees ---Jane Doe (Full Time)John Smith (Full Time)Tom Jones (Hourly)--- Full Time ---Jane DoeJohn Smith--- Hourly ---Tom Jones

 

Code List 2-15: Create, initialize, and add two full-time employees and a hourly employee. in the query, we obtain all employees and use the is operator to determine which employee type is owned by us. When I print out an employee's name, we indicate his type.

In the code block, we use the generic method OfType <T> () to obtain full-time employees and hourly employees.

 

Best practices

In TPH inheritance ing, there is a debate about when to use abstract base classes and when to create a ing condition in the object. The difficulty of using a specific base class is that it is very cumbersome to query the entire inherited instance.The best practice here is to make it an abstract type if you do not need an instance of a base class entity in your application.

If your application requires a base class instance, you can consider introducing a new inherited entity to overwrite the ing condition attribute in the base class. For example, in the preceding example, we can create a derived class UnclassifiedEmployee. Once this derived class is available, we can safely set the base class to an abstract type. This provides a simple way to avoid the problem of querying by using ing condition attributes in the base class.

When using TPH, there are several rules to remember. First, the property values of the ing condition must be independent of each other. In other words, you cannot map a row and condition to two or more types.

Second, the ing condition must be responsible for each row in the table. A row cannot be mapped to an appropriate object type. If your system is a legacy database and the rows in the table are created by another system, you have no chance of condition ing. This situation is quite troublesome. What will happen?Rows that cannot be mapped to the base class or derived class cannot be accessed by the Model.

Third, the validation Column cannot be mapped to an object attribute unless it is first used as a ing condition that is not null. This seems a little too strict. You may ask, "If you cannot set the authentication value, how can you insert a row to represent the data of the derived class ?" The answer is concise. You can directly create an instance of a derived class and add it to the context like adding an instance of another object type, object Service creates an insert statement with the correct values.

This article ends here. Thank you for reading it. This series by VolcanoCloud translation, reproduced please note the Source: http://www.cnblogs.com/VolcanoCloud/p/4490841.html

 

Entity Framework exchange QQ group: 458326058. You are welcome to join us.

Thank you for your continued attention, my blog address: http://www.cnblogs.com/VolcanoCloud/

Related Article

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.