实体框架代码第一 - 多对多外键问题

时间:2011-05-12 19:22:51

标签: mapping many-to-many ef-code-first entity-framework-4.1

我正在玩EF Code First并需要一些帮助。

用户可以创建多个帖子 用户可以推荐很多帖子 帖子可以有很多用户推荐。

鉴于此代码:

public class User
{
    public int UserID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
    public virtual ICollection<Post> Recommendations { get; set; }
}


public class Post
{
    public int PostID { get; set; }
    public int UserID { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<User> RecommendingUsers { get; set; }
}

modelBuilder.Entity<Post>()
.HasMany(x => x.RecommendingUsers)
.WithMany(x => x.Recommendations)
.Map(x => x.MapLeftKey("PostID")
    .MapRightKey("UserID")
    .ToTable("Recommendations"));

我最终在Post表中添加了一个额外的“User_UserID”列,它用于外键:

PostID(PK,int,not null)
UserID(int,not null)
User_UserID(FK,int,null)

为什么不使用UserID作为外键?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,发现了两件事:

  1. 用于映射列名的约定是User_UserID和User_ID之类的名称,而不是UserID。解决方案:
    1. 您可以改变它使用的约定。我不清楚这是否可能在EF 4.1中--Scott Gu有一篇帖子感叹它不是,但我可以看到一个Conventions属性挂在了ModelBuilder类......只有一个方法...添加( )。
    2. 您可以明确设置外键名称(见下文)。
  2. 我遇到过根据StackOverflow上的建议实际修复它的情况,但缓存的DbModel意味着它仍然出现故障,直到我实际关闭Cassini并强制dev webserver完全重启。
  3. 不幸的是,因为你没有使用框架所假定的命名约定,所以你必须在你的类中继续使用ForeignKey属性,以便将所有内容正确地绑定在一起,或者它将继续映射到错误的列名。

    设置外键名称如下:

    [ForeignKey("UserID")]
    public virtual User User { get; set; }
    

    这明确告诉框架使用UserID而不是User_UserID

    在多对多情况下,您需要使用上面的Map调用,并在两侧应用ForeignKey属性。

    这解决了我。

    我现在看到为什么斯科特哀叹离开约定 - 当你试图将现有数据库放在一起时,这真的很麻烦。