Entity framework 重写EF CodeFirst生成的数据库

Entity framework 重写EF CodeFirst生成的数据库,entity-framework,ef-code-first,Entity Framework,Ef Code First,我有一个C#项目,使用EF CodeFirst方法。我的问题是EF如何解释我的类并生成数据库表。EF推断了太多的东西,我得到的db不是我想要的方式。具体来说,它在我的一个映射类中生成额外的id列 以下是我的POCO课程: public partial class Attribute { public int Id {get;set;} public string Name {get;set;} public virtual ICollection<E

我有一个C#项目,使用EF CodeFirst方法。我的问题是EF如何解释我的类并生成数据库表。EF推断了太多的东西,我得到的db不是我想要的方式。具体来说,它在我的一个映射类中生成额外的id列

以下是我的POCO课程:

    public partial class Attribute
    {
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual ICollection<EntityAttribute> EntityAttributes {get;set;}
    }

    public partial class Grant
    {
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual ICollection<EntityAttribute> EntityAttributes {get;set;}
    }

    public partial class Donor
    {
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual ICollection<EntityAttribute> EntityAttributes {get;set;}
    }

    public enum EntityTypeEnum
    {
    Grant = 1,
    Donor = 2
    }

    public partial class EntityAttribute
    {
    public int Id {get;set;}
    public int EntityId {get;set;}
    public int AttributeId {get;set;}
    public int EntityTypeId {get;set;}
    public EntityTypeEnum EntityType
    {
       get{return (EntityTypeEnum)this.EntityTypeId;}
       set{this.EntityTypeId = (int)value;}
    }
    public virtual Grant Grant {get;set;}
    public virtual Donor Donor {get;set;}
}
公共部分类属性
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection EntityAttributes{get;set;}
}
公共部分班级补助金
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection EntityAttributes{get;set;}
}
公共部分类捐赠者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection EntityAttributes{get;set;}
}
公共枚举实体类型枚举
{
格兰特=1,
捐赠者=2
}
公共部分类EntityAttribute
{
公共int Id{get;set;}
public int EntityId{get;set;}
公共int AttributeId{get;set;}
public int EntityTypeId{get;set;}
公共EntityType枚举EntityType
{
获取{return(EntityTypeEnum)this.EntityTypeId;}
设置{this.EntityTypeId=(int)值;}
}
公共虚拟授权{get;set;}
公共虚拟施主{get;set;}
}
我的映射类是典型的,但下面是EntityAttributeMap类:

public partial class EntityAttributeMap : EntityTypeConfiguration<EntityAttribute>
{
public EntityAttributeMap()
{
this.ToTable("EntityAttribute");
this.HasKey(ea => ea.Id);
this.Property(ea => ea.EntityTypeId).IsRequired();
this.Ignore(ea => ea.EntityType);

this.HasRequired(ea => ea.Grant)
    .WithMany(g => g.EntityAttributes)
    .HasForeignKey(ea => ea.EntityId);

this.HasRequired(ea => ea.Donor)
    .WithMany(d => d.EntityAttributes)
    .HasForeignKey(ea => ea.EntityId);

this.HasRequired(ea => ea.Attribute)
    .WithMany(a => a.EntityAttributes)
    .HasForeignKey(ea => ea.AttributeId)
}
}
公共部分类EntityAttributeMap:EntityTypeConfiguration
{
公共实体属性映射()
{
此.ToTable(“EntityAttribute”);
this.HasKey(ea=>ea.Id);
this.Property(ea=>ea.EntityTypeId).IsRequired();
this.Ignore(ea=>ea.EntityType);
this.HasRequired(ea=>ea.Grant)
.WithMany(g=>g.EntityAttributes)
.HasForeignKey(ea=>ea.EntityId);
this.HasRequired(ea=>ea.Donor)
.WithMany(d=>d.EntityAttributes)
.HasForeignKey(ea=>ea.EntityId);
this.HasRequired(ea=>ea.Attribute)
.WithMany(a=>a.EntityAttributes)
.HasForeignKey(ea=>ea.AttributeId)
}
}
我的所有单元测试都按预期执行。但是,表EntityAttribute使用DonorId和GrantId列呈现。我不想要这个,因为我实际上有几十个其他的“EntityType”将用于这个场景。这就是我选择EntityTypeEnum类的原因

我做错了什么?或者是否有其他方法可以映射这些,以便EF以我想要的方式处理事情。谢谢。

话虽如此,这个模式看起来(对我来说,你的帖子并不清楚,你的意图也可能不同)太接近于一个新的模式,我感到不舒服。出于通常的原因(googleit),我不喜欢这些,而且即使EF中有
enum
支持,我也不想要那种模型

为什么不映射到另一个实体类型而不是枚举


如果您以“以下是我的业务需求;这方面的最佳模式是什么?”的形式提出问题,您可能会得到更好的答案。

我想我正按照您的建议转向EAV。我只是想提高效率。鉴于我将有许多实体映射到属性表,您是否建议为每个实体/属性组合或一个映射表中的多个实体id列创建一个单独的映射表。我想这样做的缺点是会有很多空值。另外,谢谢你的问题框架建议。很多空值可能不是问题。例如,SQL Server 2008+允许您声明列
SPARSE
,这告诉服务器“针对大部分空值进行优化”。哦,关于一个表与多个表,请阅读EF中的TPH与TPT继承建模。即使您不做继承本身,性能方面的考虑也是一样的。谢谢Craig。我可能会选择一个表,并针对空值进行优化(我不知道有关SQL Server的情况)。这是一个最多只有几十个用户的后台应用程序。不过,我会看看你的阅读建议。再次感谢。