2014年11月26日 星期三

Entity Framework Code First 繼承對應設定

TPH(Table Per Hierarchy)
基底類別和衍生類別都映射到同一張表中,通過一個鑒別欄位來識別資料是屬於基底或是衍生類別,這是預設的映射方法

Table1
namespace ConsoleApplication1.Models
{
    using System.ComponentModel.DataAnnotations;

    public class Table1
    {
        [Key]
        public int Table1Id { get; set; }

        public int C1 { get; set; }

        public int C2 { get; set; }
    }
}

Table2
namespace ConsoleApplication1.Models
{
    public class Table2 : Table1
    {
        public int C3 { get; set; }

        public int C4 { get; set; }
    }
}

新增幾筆資料
namespace ConsoleApplication1
{
    using ConsoleApplication1.Models;

    class Program
    {
        static void Main(string[] args)
        {
            using (DemoContext db = new DemoContext())
            {
                db.Table1.Add(new Table1 { C1 = 1, C2 = 2 });
                db.Table2.Add(new Table2 { C1 = 1, C2 = 2, C3 = 3, C4 = 4 });
                db.SaveChanges();
            }
        }
    }
}

TPH資料表建立的樣子

TPH資料儲存的樣子

可以透過Fluent API設定用來識別的欄位,和識別資料的值
namespace ConsoleApplication1.Models
{
    using System.Data.Entity;

    public class DemoContext : DbContext
    {
        public DbSet<Table1> Table1 { get; set; }
        public DbSet<Table2> Table2 { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Table1>()
                .Map(x=> {
                    x.ToTable("Table1");
                    x.Requires("QQ").HasValue("AA");
                })
                .Map<Table2>(x=> {
                    x.Requires("QQ").HasValue("BB");
                });
        }
    }
}

設定後資料儲存的樣子


TPT(Table Per Type)
把資料映射到各自的資料表中,並在衍生類別的資料表中自動生成外鍵來關聯基厎類別的資料表,使用方式很簡單,只要指定各自資料表的名稱就行了
namespace ConsoleApplication1.Models
{
    using System.Data.Entity;

    public class DemoContext : DbContext
    {
        public DbSet<Table1> Table1 { get; set; }
        public DbSet<Table2> Table2 { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Table1>().ToTable("Table1");
            modelBuilder.Entity<Table2>().ToTable("Table2");
        }
    }
}

TPT資料表建立的樣子

TPT資料儲存的樣子


TPC(Table Per Concreate Type)
除了資料映射到各自的資料表之外,衍生類別的資料表中還會包含基底類別的欄位
透過FluentAPI設定Map即可
namespace ConsoleApplication1.Models
{
    using System.Data.Entity;

    public class DemoContext : DbContext
    {
        public DbSet<Table1> Table1 { get; set; }
        public DbSet<Table2> Table2 { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Table1>()
                .Map(x =>
                {
                    x.ToTable("Table1");
                })
                .Map<Table2>(x =>
                {
                    x.ToTable("Table2");
                    x.MapInheritedProperties();
                });
        }
    }
}

TPC資料表建立的樣子

TPC資料儲存的樣子