2017-09-06 26 views
10

我有一個類TypeEntity,它將充當幾十個實體的基類。我正在使用TPC,所以我需要將基類中的所有屬性映射到具有具體類的名稱的表,並將Key字段設置爲數據庫生成。使用實體框架中的自定義慣例控制列映射6

目前我有EntityTypeConfiguration的,看起來像這樣每個實體類型這樣做:

class LineItemType : EntityTypeConfiguration<Models.LineItemType> 
{ 
    public LineItemType() 
    { 
     this.Property(e => e.Key) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     this.Map(e => e.MapInheritedProperties() 
         .ToTable(nameof(LineItemType))); 
    } 
} 

這工作得很好,但很重複。我必須記得爲從TypeEntity繼承的每種類型創建一個配置類,設置密鑰並映射繼承的屬性。這似乎是一個自定義Convention的理想情況。


我創建了一個TypeEntityTpcConventionConvention如下:

class TypeEntityTpcConvention : Convention 
{ 
    public TypeEntityTpcConvention() 
    { 
     this.Types<TypeEntity>() 
      .Configure(e => e.Property(p => p.Key) 
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)); 
    } 
} 

其中一期工程設置Key爲生成的數據庫,但我找不到任何辦法從裏面約定的訪問屬性表映射。


理想情況下,我希望這樣的事情:

this.Types<TypeEntity>() 
    .Configure(e => e.MapInheritedProperties() 
    .ToTable(e.ClrType.Name)); 

甚至一個電話這樣對於需要映射每個屬性:

this.Types<TypeEntity>() 
    .Configure(e => e.Property(p=>p.Key) 
        .ToTable(e.ClrType.Name)); 

均未似乎存在。有沒有什麼辦法可以控制Convention內部的物業映射?


經過一些額外的研究,它看起來像有可作爲IStoreModelConventionIConceptualModelConvention更先進的會議場所,但有用的文檔,如何使用這些嚴重缺乏。經過幾個小時用斷點和觀察窗口戳穿它們,我還沒有想出如何使用這些接口來控制列映射。


我目前的解決方案是使用反射來發現,從TypeEntityOnModelCreating繼承了所有類型和屬性映射到正確的表。這是有效的,但如果可能的話,我寧願使用一個約定,因爲這看起來好像是爲約定製定的類型。我覺得我失去了一些明顯的東西。

+0

的問題是沒有得到類的名稱,它是'.ToTable'(或其他允許我將屬性重定向到不同表格的東西)似乎不存在於「Convention」的上下文中。 –

+0

啊..我誤解了。我將刪除評論。 –

+0

我有一個解決方案。這不完全是一個慣例,但它確實會自動應用於您指定的所有類型(即,您不必爲每個實體添加一行新的配置)。如果你有興趣,我可以發佈它。 –

回答

9

據我所見,你可以在你的DbContextOnModelCreating方法中編寫類型配置,它與你在問題中已經提到的代碼非常相似。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Types<TypeEntity>().Configure(c => 
    { 
     c.HasKey(p => p.Key); 
     // probably not needed, but won't do any harm 
     c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     c.ToTable(c.ClrType.Name); 
    }); 
} 

如果此方法有任何問題,請告訴我,我將重新訪問該主題。

編輯:

完全相同的原理可以約定適用:

class TypeEntityConvention : Convention 
{ 
    public TypeEntityConvention() 
    { 
     this.Types<TypeEntity>().Configure(c => 
     { 
      c.HasKey(p => p.Key); 
      c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
      c.ToTable(c.ClrType.Name); 
     }); 
    } 
} 

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Conventions.Add<TypeEntityConvention>(); 
} 
+0

這也是我的解決方案。不是一個約定,但它是通用的,沒有反射。 –

+0

我喜歡你的解決方案比我目前使用的解決方案更好,但這真的感覺像'Convention'應該能夠處理的東西。在這一點上,我有一個可行的解決方案,這只是我的願望,要學會如何有效地使用約定,這就是現在要解決這個問題。 –

+0

@BradleyUffner看到我的更新。 – grek40