簡體   English   中英

如何使用給定的約定配置實體框架?

[英]How to configure Entity Framework with given conventions?

我有一個已經創建了DB(Sql2008)和Models(C#)的MVC4項目,因此無法同時更改它們的名稱。 我開始使用EF4.1對每個正在使用的類進行自定義配置,因此在創建模型時,所有內容都映射到數據庫。 通常,所有表的名稱均為“ tbl_X _” +實體名稱,主鍵為“實體名稱” +“ 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
        }
    }

構建時出現錯誤

“類型'Company'的屬性只能映射一次。”

我絕對知道會發生這種情況,因為我映射了兩次,一個映射基於基,另一個映射於派生類。 我想知道,如果tableName和primaryKeyName都有第二個映射,是否可以覆蓋第一個。

提前致謝!

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

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

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

滿意的答案,但不能滿足所有要求。 到目前為止,這是我得到的解決方案:

我將所有表和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;
        }

    }



}

然后在我的自定義配置類上,我僅映射其他列,前鍵,關系。 例如:

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

隨時添加您的評論!

謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM