为什么我使用Entity Framework Code First外键属性获得额外的外键列?

时间:2012-06-06 06:18:18

标签: entity-framework ef-code-first

我最近遇到了Entity Framework Code First的这个奇怪问题。

我的班级看起来像这样

public class Status
{
        [Key]
        public int StatusID { get; set; }     
        public string Name { get; set; }
        public int MemberID { get; set; }

        [ForeignKey("MemberID")]
        public virtual Member Member { get; set; }                

        public int PosterID { get; set; }

        [ForeignKey("PosterID")]
        public virtual Member Poster { get; set; }        

        public virtual ICollection<StatusLike> StatusLikes { get; set; }        
        public virtual ICollection<StatusComment> StatusComments { get; set; }
}

我的会员班看起来像这样

 public class Member
    {
        [Key]
        public int MemberID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Bio { get; set; }

        public virtual ICollection<MemberCourseTaken> MemberCourseTakens { get; set; }
        public virtual ICollection<Status> Statuses { get; set; }
        public virtual ICollection<Club> FoundedClubs { get; set; }

        public string EmailAddress { get; set; }
        public string Password { get; set; }
        public string Phone { get; set; }

        public int AccountSourceID { get; set; }
        public AccountSource AccountSource { get; set; }

        public int AddressID { get; set; }
        public Address Address { get; set; }
        public string ProfilePhoto { get; set; }

        public int MemberRankID { get; set; }
        public MemberRank MemberRank { get; set; }
        public DateTime Created { get; set; }
        public DateTime Modified { get; set; }
    }

无论出于何种原因,创建的数据库表都包含以下列

StatusID
Name
MemberID
PosterID
Member_MemberID

MemberIDPosterIDMember_MemberID是外键。

如何防止生成Member_MemberID

2 个答案:

答案 0 :(得分:15)

由于Member_MemberID属性,您的Member.Statuses列已创建。我可以想象这不是你想要的。可能成员和状态应该彼此独立存在,因此您需要一个联结表。

我不知道您是否已使用DbContext的OnModelCreating覆盖,但这是更改成员和状态之间映射的地方:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<Member>().HasMany(m => m.Statuses).WithMany();
}

这将创建一个表MemberStatuses表,其中两个Id列作为外键。这是一种在关联的“其他”端没有导航属性的情况下建模多对多关系的方法。 (我认为您不希望Members中有Status属性。

答案 1 :(得分:6)

我之前见过这个。在我的情况下(使用EF 6.1),这是因为我的Fluent API Mapping设置如下:

// In my EntityTypeConfiguration<Status>
HasRequired(x => x.Member).WithMany().HasForeignKey(x => x.MemberID);

该代码完全正常,但它没有告诉EF我的Member类的集合导航属性Status已被考虑在内。因此,当我在Member类中明确处理Status导航属性的存在时,我现在留下了一个孤立的相关集合属性。作为集合的孤立属性告诉EF我的Status类需要有一个外键。所以它在Status类上创建了它。

要解决这个问题,我必须100%明确。

HasRequired(x => x.Member).WithMany(x => x.Statuses).HasForeignKey(x => x.MemberID)

Statuses中的Member Collection属性可能需要一个属性来告诉它已经考虑过,而不是自动创建映射。我不知道那个属性。