2013-03-21 61 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()); 
}