映射一

Mapping the Table-Per-Hierarchy (TPH) Inheritance

模型文件

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            modelBuilder.Entity<Course>()
                .Map<Course>(m => m.Requires("Type").HasValue("Course"))
                .Map<OnlineCourse>(m => m.Requires("Type").HasValue("OnlineCourse"));
        }
    }//class

    public class Course
    {
        public int CourseID { get; set; }

        public string Title { get; set; }
        public int Credits { get; set; }

    }//class

    public partial class OnlineCourse : Course
    {
        public string URL { get; set; }

    }//class
}

对应的数据库代码:

CREATE TABLE [dbo].[Course] (
    [CourseID] INT            IDENTITY (1, 1) NOT NULL,
    [Title]    NVARCHAR (MAX) NULL,
    [Credits]  INT            NOT NULL,
    [URL]      NVARCHAR (MAX) NULL,
    [Type]     NVARCHAR (128) NOT NULL,
    CONSTRAINT [PK_dbo.Course] PRIMARY KEY CLUSTERED ([CourseID] ASC)
);

此是默认的策略,去掉建造者中的配置信息,代码如下:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }//class

    public class Course
    {
        public int CourseID { get; set; }

        public string Title { get; set; }
        public int Credits { get; set; }

    }//class

    public partial class OnlineCourse : Course
    {
        public string URL { get; set; }

    }//class
}

生成的数据库代码:

CREATE TABLE [dbo].[Course] (
    [CourseID]      INT            IDENTITY (1, 1) NOT NULL,
    [Title]         NVARCHAR (MAX) NULL,
    [Credits]       INT            NOT NULL,
    [URL]           NVARCHAR (MAX) NULL,
    [Discriminator] NVARCHAR (128) NOT NULL,
    CONSTRAINT [PK_dbo.Course] PRIMARY KEY CLUSTERED ([CourseID] ASC)
);

可见,鉴别器列被命名为Discriminator,其保存记录的类名称。

映射二

Mapping the Table-Per-Type (TPT) Inheritance

模型文件:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            //TPT
            modelBuilder.Entity<Course>().ToTable("Course");
            modelBuilder.Entity<OnlineCourse>().ToTable("OnlineCourse");
        }
    }

    public class Course
    {
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
    }

    public partial class OnlineCourse : Course
    {
        public string URL { get; set; }
    }
}

将类型名称与表名称对应,生成的数据库代码:

CREATE TABLE [dbo].[Course] (
    [CourseID] INT            IDENTITY (1, 1) NOT NULL,
    [Title]    NVARCHAR (MAX) NULL,
    [Credits]  INT            NOT NULL,
    CONSTRAINT [PK_dbo.Course] PRIMARY KEY CLUSTERED ([CourseID] ASC)
);

------------------------------------------------------------------------------------------
CREATE TABLE [dbo].[OnlineCourse] (
    [CourseID] INT            NOT NULL,
    [URL]      NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.OnlineCourse] PRIMARY KEY CLUSTERED ([CourseID] ASC),
    CONSTRAINT [FK_dbo.OnlineCourse_dbo.Course_CourseID] FOREIGN KEY ([CourseID]) REFERENCES [dbo].[Course] ([CourseID])
);


GO
CREATE NONCLUSTERED INDEX [IX_CourseID]
    ON [dbo].[OnlineCourse]([CourseID] ASC);

派生类对应的表会有一个外键,将派生表的主键与基类对应的主表关联,形成0/1..1的关系。

映射三

Mapping the Table-Per-Concrete Class (TPC) Inheritance

模型:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            //TPC
            modelBuilder.Entity<OnlineCourse>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("OnlineCourse");
            });
        }
    }

    public class Course
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }

        public string Title { get; set; }
        public int Credits { get; set; }
    }

    public partial class OnlineCourse : Course
    {
        public string URL { get; set; }
    }
}

生成的数据库代码:

CREATE TABLE [dbo].[Course] (
    [CourseID] INT            NOT NULL,
    [Title]    NVARCHAR (MAX) NULL,
    [Credits]  INT            NOT NULL,
    CONSTRAINT [PK_dbo.Course] PRIMARY KEY CLUSTERED ([CourseID] ASC)
);

-----------------------------------------------------------------------------------------
CREATE TABLE [dbo].[OnlineCourse] (
    [CourseID] INT            NOT NULL,
    [Title]    NVARCHAR (MAX) NULL,
    [Credits]  INT            NOT NULL,
    [URL]      NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.OnlineCourse] PRIMARY KEY CLUSTERED ([CourseID] ASC)
);

注意,主键在整个继承层次结构上唯一,而不是单个表上唯一。

映射四

Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)

模型:

using System;
using System.Data.Entity;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Department> Departments { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Department>()
                .Map(m =>
                {
                    m.Properties(t => new { t.DepartmentID, t.Name });
                    m.ToTable("Department");
                })
                .Map(m =>
                {
                    m.Properties(t => new { t.DepartmentID, t.StartDate });
                    m.ToTable("DepartmentDetails");
                });
        }
    }

    public class Department
    {
        public int DepartmentID { get; set; }
        public string Name { get; set; }
        public DateTime StartDate { get; set; }
    }
}

生成的数据库代码:

CREATE TABLE [dbo].[Department] (
    [DepartmentID] INT            IDENTITY (1, 1) NOT NULL,
    [Name]         NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.Department] PRIMARY KEY CLUSTERED ([DepartmentID] ASC)
);

----------------------------------------------------------------------------------------
CREATE TABLE [dbo].[DepartmentDetails] (
    [DepartmentID] INT      NOT NULL,
    [StartDate]    DATETIME NOT NULL,
    CONSTRAINT [PK_dbo.DepartmentDetails] PRIMARY KEY CLUSTERED ([DepartmentID] ASC),
    CONSTRAINT [FK_dbo.DepartmentDetails_dbo.Department_DepartmentID] FOREIGN KEY ([DepartmentID]) REFERENCES [dbo].[Department] ([DepartmentID])
);


GO
CREATE NONCLUSTERED INDEX [IX_DepartmentID]
    ON [dbo].[DepartmentDetails]([DepartmentID] ASC);

 

每个表都包含主键,第一个表的主键Identity,第二个表的主键无Identity,外键将两个表的主键关联。

映射五

Mapping Multiple Entity Types to One Table in the Database (Table Splitting)

这个模式主要用于懒惰加载,模型文件:

using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace DataAnnotations
{
    public class TestContext : DbContext
    {
        public DbSet<Instructor> Instructors { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Instructor>()
                .HasRequired(t => t.OfficeAssignment)
                .WithRequiredPrincipal(t => t.Instructor);

            modelBuilder.Entity<Instructor>().ToTable("Instructor");
            modelBuilder.Entity<OfficeAssignment>().ToTable("Instructor");
        }
    }// TestContext

    public class Instructor
    {
        public int InstructorID { get; set; }
        public string Name { get; set; }

        // 导航属性
        public OfficeAssignment OfficeAssignment { get; set; }
    }

    public class OfficeAssignment
    {
        [Key]
        public int InstructorID { get; set; }
        public string Location { get; set; }

        // 导航属性
        public Instructor Instructor { get; set; }
    }

}

 

生成的数据库代码为:

CREATE TABLE [dbo].[Instructor] (
    [InstructorID] INT            IDENTITY (1, 1) NOT NULL,
    [Name]         NVARCHAR (MAX) NULL,
    [Location]     NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.Instructor] PRIMARY KEY CLUSTERED ([InstructorID] ASC)
);