none
EF的TPH(Code-first)設計的資料表產生問題 RRS feed

  • 問題

  • hello, 各位好..

    我用TPH的設計方式產生table..

    如下代碼:

    public virtual DbSet<Product> Products { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Product>()
                    .Map<Camera>(m =>
                        m.MapInheritedProperties()
                            .ToTable("Products")
                            .Requires("Discriminator")
                            .HasValue("Camera")
                    )
                    .Map<SingleReflexCamera>(m =>
                        m.MapInheritedProperties()
                            .ToTable("Products")
                            .Requires("Discriminator")
                            .HasValue("SingleReflexCamera")
                    )
                    .Map<Lens>(m =>
                        m.MapInheritedProperties()
                            .ToTable("Products")
                            .Requires("Discriminator")
                            .HasValue("Lens")
                    );
    
                base.OnModelCreating(modelBuilder);
            }
        }

    各資料表的class:

    public class Product
        {
            public int Id { get; set; }
            public string Caption { get; set; }
            public string TypeNumber { get; set; }
            public string Manufacturer { get; set; }
        }
    
        public class Camera : Product
        {
            public string Lens { get; set; }
        }
    
        public class SingleReflexCamera : Product
        {
            public string LensMount { get; set; }
        }
    
        public class Lens : Product
        {
            public string FocalLength { get; set; }
            public string MaxAperture { get; set; }
        }

    這其實是照抄MVC開發美學的範例來試試...

    但是他從DB(SQL2008R2)自動產生Product的資料表後, 會另外產生名為Product1的奇怪資料表..

    Product1欄位: {Id, Caption, TypeNumber, Manufacturer}

    我不太理解為什麼會出現這資料表

    請問這是正常的現象嗎?....



    • 已編輯 StoRAID 2016年8月2日 上午 07:42
    • 已編輯 FlyingBread 2016年8月2日 上午 10:36 edited
    2016年8月2日 上午 07:41

解答

  • 這個問題看起來有點像是 Entity Framework 本身的特殊設計 (Database Creation 這部份的),當 EF 啟動 Create Database 程序時,它會針對 Entity 的註冊資訊發出 CREATE TABLE 的指令,不過它似乎不會去確認表格是否有成功建立,就我的實驗觀察,它會發出兩次相同的 CREATE TABLE 指令 (猜測一個是 Entity 本身,另一個是 Map 後的結構),但程式沒有因為表格已存在而發生錯誤,所以推定它不會攔截這個錯誤狀況,我想應該和 TPH 的機制有關,因為 EF 的 TPH 是一個表格放多個 Entity。

    所以這個問題也可以說是正常現象,多的那個表格放在那裡也沒差,因為程式永遠不會動到它,但若是看這個表格礙眼的話,也可以在 Entity() 後直接給它 DB 的表格名稱來解決:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>().ToTable("Products")
            .Map<Camera>(m =>
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("Camera")
            )
            .Map<SingleReflexCamera>(m =>
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("SingleReflexCamera")
                )
            .Map<Lens>(m => 
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("Lens")
                );
                
        base.OnModelCreating(modelBuilder);
    }
    


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已提議為解答 ThankfulHeart 2016年8月6日 上午 05:47
    • 已標示為解答 StoRAID 2016年8月7日 上午 04:50
    2016年8月6日 上午 01:01
    版主

所有回覆

  • 這個問題看起來有點像是 Entity Framework 本身的特殊設計 (Database Creation 這部份的),當 EF 啟動 Create Database 程序時,它會針對 Entity 的註冊資訊發出 CREATE TABLE 的指令,不過它似乎不會去確認表格是否有成功建立,就我的實驗觀察,它會發出兩次相同的 CREATE TABLE 指令 (猜測一個是 Entity 本身,另一個是 Map 後的結構),但程式沒有因為表格已存在而發生錯誤,所以推定它不會攔截這個錯誤狀況,我想應該和 TPH 的機制有關,因為 EF 的 TPH 是一個表格放多個 Entity。

    所以這個問題也可以說是正常現象,多的那個表格放在那裡也沒差,因為程式永遠不會動到它,但若是看這個表格礙眼的話,也可以在 Entity() 後直接給它 DB 的表格名稱來解決:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>().ToTable("Products")
            .Map<Camera>(m =>
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("Camera")
            )
            .Map<SingleReflexCamera>(m =>
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("SingleReflexCamera")
                )
            .Map<Lens>(m => 
                m.MapInheritedProperties()
                .ToTable("Products")
                .Requires("Discriminator")
                .HasValue("Lens")
                );
                
        base.OnModelCreating(modelBuilder);
    }
    


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已提議為解答 ThankfulHeart 2016年8月6日 上午 05:47
    • 已標示為解答 StoRAID 2016年8月7日 上午 04:50
    2016年8月6日 上午 01:01
    版主
  • 感謝回覆...
    2016年8月7日 上午 04:50