我试图使用一个通用的EntityTypeConfiguration类来为我的所有实体配置主键,以便每个派生的配置类不会重复。我的所有实体都实现了一个公共接口IEntity(它表示每个实体必须具有int类型的Id属性)。
我的配置基类如下所示:
public class EntityConfiguration<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : class , IEntity {
public EntityConfiguration() {
HasKey( e => e.Id );
Property( e => e.Id ).HasDatabaseGeneratedOption( DatabaseGeneratedOption.Identity );
}
}
然后,每个实体都有自己的特定配置类,如下所示:
public class CustomerConfiguration : EntityConfiguration<Customer> {
public CustomerConfiguration() : base() {
// Entity specific configuration here
}
}
它编译得很好,但我遇到的问题是,在运行时,当EF 4.1 RC尝试创建模型时,我会引发以下异常:
System.InvalidOperationException是
未处理的消息=关键组件
'Id'不是声明的属性
输入“客户”。验证它有
未被明确排除在外
模型,它是一个有效的原语
属性。来源=的EntityFramework
如果我将CustomerConfiguration类更改为从EntityTypeConfiguration <Customer>扩展并重复主键配置,那么它工作正常,但我失去了共享公共配置的能力(DRY主体是动机)。
- 我在这里做错了吗?
- 是否有另一种方法可以在实体之间共享通用配置?
这里参考其他课程:
public interface IEntity {
int Id { get; set; }
}
public class Customer : IEntity {
public virtual int Id { get; set; }
public virtual string name { get; set; }
}
谢谢!
我认为你不需要经历所有这些。 EF 4.1 Code First使用了很多约定优于配置,通过这种方式,实体的Id属性被配置为主键。因此,通过在您的实体上实现IEntity接口,您将使用Id作为主键来设置它们。
以下是ADO.NET团队博客的链接,该博客解释了主键约定的工作原理 - Code First的约定
我认为你不需要经历所有这些。 EF 4.1 Code First使用了很多约定优于配置,通过这种方式,实体的Id属性被配置为主键。因此,通过在您的实体上实现IEntity接口,您将使用Id作为主键来设置它们。
以下是ADO.NET团队博客的链接,该博客解释了主键约定的工作原理 - Code First的约定
看起来这些配置有一些接口问题。如果你改变它是有效的 IEntity
至 EntityBase
:
public class EntityBase
{
public virtual int Id { get; set; }
}
public class Customer : EntityBase
{
public virtual string Name { get; set; }
}
public class EntityConfiguration<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : EntityBase
{
public EntityConfiguration()
{
HasKey(e => e.Id);
Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class CustomerConfiguration : EntityConfiguration<Customer>
{
public CustomerConfiguration()
: base()
{
...
}
}
您可以在类上创建静态方法并将实体传递给它。例如:
public class CustomerConfiguration : EntityConfiguration<Customer>
{
public CustomerConfiguration()
: base()
{
...
EntityConfiguration.Configure(this);
}
}
public static class EntityConfiguration
{
public static void Configure<TEntity>(EntityTypeConfiguration<TEntity> entity) where TEntity : EntityBase
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
当我有具有Id属性的通用抽象类以及抽象成员和自定义属性的实现时,我与EF5.0有类似的问题。
看起来像实体框架代码首先只查找映射的类属性。
我试图使用反射器 - 似乎我是对的,但不确定这100%。
而且,幸运的是,找到了解决方案:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<MyEntity>()
.Map(m =>
{
**m.MapInheritedProperties();**
});
}
所以在我的情况下:要从基类映射属性我必须添加一行代码m.MapInheritedProperties()...