Code First: 五大映射模式

映射一

Mapping the Table-Per-Hierarchy (TPH) Inheritance數據庫

模型文件app

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
}

對應的數據庫代碼:ide

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

此是默認的策略,去掉建造者中的配置信息,代碼以下:ui

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
}

生成的數據庫代碼:spa

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,其保存記錄的類名稱。code

映射二

Mapping the Table-Per-Type (TPT) Inheritanceblog

模型文件:繼承

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

將類型名稱與表名稱對應,生成的數據庫代碼:ip

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的關係。ci

映射三

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)
);
相關文章
相關標籤/搜索