0

我與DB(SQL2008)和模式(C#)已經創建了一個MVC4項目,所以它是不可能對他們都沒有更改名稱。我開始使用EF4.1以及我正在使用的每個類的自定義配置,因此創建所有內容的模型都映射到數據庫。大多數情況下,所有表的名稱均爲「tbl_X_」+ entityName,主鍵爲entityName +「ID」。其他人有「tbl」+ entityName和其他主鍵。爲了避免重複的代碼,我創建了一個定製EntityTypeConfiguration:如何使用給定的約定配置實體框架?

public abstract class BaseConfiguration<T> : EntityTypeConfiguration<T> 
     where T: class 
    { 
     public BaseConfiguration() 
     { 
      Map(x => x.ToTable("tbl_X_" + typeof(T).Name)); 

      var parm = Expression.Parameter(typeof(T), typeof(T).Name); 
      var propExpression = Expression.Lambda<Func<T, int>> 
       (Expression.Convert(Expression.Property(parm, "Id"), typeof(int)), parm); 
      Property(propExpression).HasColumnName(typeof(T).Name + "_ID"); 
     } 
    } 

這工作對大多數的情況下,除了當表名稱不符合該約定,我映射表,其給出的名字:

public class CompanyConfiguration : BaseConfiguration<Company> 
    { 
     public CompanyConfiguration() 
     { 
      Map(x => x.ToTable("tbl_Company")); 
      //Key does follow convention 
     } 
    } 

當我建立我得到錯誤

「類型'公司'的屬性只能被映射一次。」

我是絕對知道發生這種情況的原因,我映射兩次,一次在基地和其他的派生類。我想知道是否有可能覆蓋第一個如果有第二個映射爲tableName和primaryKeyName。

在此先感謝!

編輯:一些實體需要的歧視。

Map(x => x.Requires("discriminatorColumn") 
          .HasValue(value) 
          .HasColumnType("dataType") 
          .IsRequired()) 
          .ToTable("tbl_TableName"); 

回答

0

讚賞的答案,但沒有填寫的所有要求。這是迄今爲止我已經得到了解決:

我感動了所有表的PrimaryKey映射到BaseConfiguration類:

public class BaseConfiguration<T> : EntityTypeConfiguration<T> 
    where T : class 
{ 
    public BaseConfiguration() 
    { 
     TableNameConvention(); 
     PrimaryKeyConvention(); 
    } 

    private void TableNameConvention() 
    { 
     switch (typeof(T).Name) 
     { 
      case "entityA": 
       ToTable("vw_entityA"); 
       break; 
      case "entityB": 
       ToTable("tbl_entityB"); 
       break; 
      case "entityC": 
       Map(x => x.Requires("discriminatorColumn") 
         .HasValue(value) 
         .HasColumnType("dataType") 
         .IsRequired()) 
         .ToTable("tblentityC"); 
       break; 

      default: 
       ToTable("tbl_X_" + typeof(T).Name); 
       break; 
     } 
    } 

    private void PrimaryKeyConvention() 
    { 
     var type = typeof(T); 
     var parm = Expression.Parameter(type, type.Name); 
     var propExpression = Expression.Lambda<Func<T, int>> 
       (Expression.Convert(Expression.Property(parm, "Id"), typeof(int)), parm); 

     switch (type.Name) 
     { 
      case "entityB": 
       Property(propExpression).HasColumnName("IdEntityB"); 
       break; 
      default: 

       Property(propExpression).HasColumnName(type.Name + "_ID"); 

       break; 
     } 

    } 



} 

然後在我的自定義配置類,我只地圖等欄目,foreing鍵,關係。例如:

public class EntityXConfiguration : BaseConfiguration<EntityX> 
    { 
     public EntityXConfiguration() 
     { 
      ////Not needed here anymore. Moved to baseconfiguration 
      //Property(x => x.Id).HasColumnName("EntityX_ID"); 
      //ToTable("tbl_X_EntityX"); 
      //// 


      Property(x => x.ParentId).HasColumnName("EntityXParent_ID"); 
      Property(x => x.Name).HasColumnName("EntityXName"); 


      Ignore(x => x.EntityXProperty); 

      ////Other mappings... 
     } 
    } 

隨意添加您的評論!

謝謝!

0

上BaseConfiguration構造函數總是這樣,總是會有運行CompanyConfiguration的代碼塊之前的地圖行動執行CompanyConfiguration的構造函數之前運行。我不知道重寫地圖調用以允許它被第二次調用。然而,解決這個問題的一個選擇可能是有一些重載的構造函數來解決這個問題。

事情是子類:

public class CompanyConfiguration : BaseConfiguration<Company> 
{ 
    private readonly string customTableMap = "tbl_Company"; 

    public CompanyConfiguration() : base(customTableMap) { } 
} 

和父:

public abstract class BaseConfiguration<T> : EntityTypeConfiguration<T> 
    where T: class 
{ 
    private readonly string defaultTableMap = "tbl_X_" + typeof(T).Name; 

    public BaseConfiguration(): this(defaultTableMap) { } 

    public BaseConfiguration(string tableMap) 
    { 
     Map(x => x.ToTable(tableMap)); 

     var parm = Expression.Parameter(typeof(T), typeof(T).Name); 
     var propExpression = Expression.Lambda<Func<T, int>> 
      (Expression.Convert(Expression.Property(parm, "Id"), typeof(int)), parm); 
     Property(propExpression).HasColumnName(typeof(T).Name + "_ID"); 
    } 
} 
+0

@AlexC您好,感謝您的回覆。非常感謝!我之前曾考慮過這個解決方案,我想我也必須包含customPrimaryKeyMap作爲參數。到目前爲止沒有問題。但是,有一些實體需要歧視,所以如果可能的話,我想要第二個映射。請閱讀我的文章,因爲我會提交一個修改。此外,我還將添加迄今爲止獲得的解決方案。隨意添加您的評論,因爲我知道它可能不是最好的解決方案性能明智。 – rkrdo 2013-03-06 17:11:59