2013-03-21 62 views
1

我有幾個實例除了類名稱都相同,每個實例都映射到對應的相同表。每個表的映射類似於以下內容:無法使用泛型創建EF代碼第一個映射類

modelBuilder.Entity<Foo>().Map(x => 
{ 
    x.MapInheritedProperties(); 
    x.ToTable("Foo"); 
}) 

此方法有效,但重複。

我創建了這個類,希望擺脫重新定位。爲簡潔起見,此處簡化。

public class Generic<T> 
{ 
    public Generic(DbModelBuilder modelBuilder, string tableName) 
    { 
     modelBuilder.Entity<T>().Map(m => 
     { 
      m.MapInheritedProperties(); 
      m.ToTable(tableName); 
     }); 
    } 
} 

我得到以下編譯器錯誤,我不明白:

The type 'T' must be a reference type in order to use it as parameter 'TEntityType' in the generic type or method 'System.Data.Entity.DbModelBuilder.Entity<TEntityType>()' 
  • 像許多程序員的.Net我使用泛型了很多,但不經常寫他們。
  • 我已經使用EF一段時間了,但我對Code First很新穎
  • 我做了很多搜索和關閉SO沒有運氣。
  • 我在做什麼錯?我不明白什麼?

由於提前, 吉姆

回答

3

只需添加泛型參數約束where T : class

public class Generic<T> 
    where T : class 
{ 
    public Generic(DbModelBuilder modelBuilder, string tableName) 
    { 
     modelBuilder.Entity<T>().Map(m => 
     { 
      m.MapInheritedProperties(); 
      m.ToTable(tableName); 
     }); 
    } 
} 

相同的約束上DbModelBuilder.Entity<T>方法存在,這就是爲什麼你需要在你的泛型類相同的約束。

3

錯誤指出您的通用缺少class約束。關於「類型參數的限制」的Read here

所以Generic<T>應被聲明爲

public class Generic<T> where T: class 
{ 
    public Generic(DbModelBuilder modelBuilder, string tableName) 
    { 
     modelBuilder.Entity<T>().Map(m => 
     { 
      m.MapInheritedProperties(); 
      m.ToTable(tableName); 
     }); 
    } 
} 

不過,我會建議使用EntityTypeConfiguration。這個類將允許你從上下文中分離出實體映射並實現你想要的一種繼承。

例如:

public abstract class EntityConfiguration<T> : EntityTypeConfiguration<T> 
    where T : Entity 
{ 
    protected EntityConfiguration() 
    { 
     ToTable(typeof(T).Name); 

     // All primary keys are named as <EntityName>Id 
     Property(e => e.Id) 
      .HasColumnName(typeof(T).Name + "Id"); 
    } 
} 

此類規定,所有實體將具有映射到表,它的名字是等於類型的名稱和每個表具有名稱<TableName>Id一個主鍵列。

那麼對於實體Foo映射配置可以聲明如下:

public class FooConfiguration : EntityConfiguration<Foo> 
{ 
    public FooConfiguration() 
    { 
     Map(m => m.MapInheritedProperties()); 
     // add you mapping logic here 
    } 
} 

然後配置是否應登記的DbContext:

public class MyDbContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new FooConfiguration()); 
    } 
} 
+0

感謝您提供了很好的答案和額外的信息。我已經將早先的答覆標記爲答案。但是,我想讓你知道我讚賞其他信息。我總是很欣賞學習新東西。 – 2013-03-21 22:08:13

+0

@JimReineri歡迎您。 – 2013-03-22 09:25:15

0

EF提供了一個類,它允許你這樣做:

class SomeEntityMapping : EntityTypeConfiguration<SomeEntity> 
{ 
    public SomeEntityMapping() 
    { 
     ToTable("My_Entity"); 
     HasKey(e => e.Id); 
     //... 
    } 
} 

然後,在你的DbCon文本,重寫OnModelCreating並將映射添加到配置中:

protected override void OnModelCreating(DbModelBuilder builder) 
{ 
    builder.Configurations.Add(new MyEntityConfiguration()); 
}