复合密钥和分离的身份密钥

Composite Keys and separated Identity Key

请阅读该问题:Create code first, many to many, with additional fields in association table

这是来自 OP 的场景:

public class Member
{
    public int MemberID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int CommentID { get; set; }
    public string Message { get; set; }

    public virtual ICollection<Member> Members { get; set; }
}

public class MemberComment
{
    public int MemberID { get; set; }
    public int CommentID { get; set; }
    public int Something { get; set; }
    public string SomethingElse { get; set; }
}

接受的答案是:

public class MemberComment
{
    [Key, Column(Order = 0)]
    public int MemberID { get; set; }
    [Key, Column(Order = 1)]
    public int CommentID { get; set; }

    public virtual Member Member { get; set; }
    public virtual Comment Comment { get; set; }

    public int Something { get; set; }
    public string SomethingElse { get; set; }
}

现在,我的问题是:如果我想添加另一个标识字段,例如 Guid 或 AutoInc int,该怎么办,例如:

    public int MemberCommentID { get; set; }

我不是在讨论它是不是更好的方法,我想知道我是怎么做到的?

我在想这样的事情

public class MemberComment
{
    [Key, Column(Order = 0)]
    public int MemberCommentID { get; set; }

    [Key, Column(Order = 1)]
    public int MemberID { get; set; }
    [Key, Column(Order = 2)]
    public int CommentID { get; set; }

    public virtual Member Member { get; set; }
    public virtual Comment Comment { get; set; }

    public int Something { get; set; }
    public string SomethingElse { get; set; }
}

但是EF会(我认为)使用键中的3个字段,当右边是MemberCommentID是一个键时,MemberID+CommentID是另一个键。

在这种情况下,为什么不在 MemberIDCommentID 上使用 ForeignKey

public class MemberComment
{
    [Key]
    public int MemberCommentID { get; set; }

    [ForeignKey]
    public int MemberID { get; set; }
    [ForeignKey]
    public int CommentID { get; set; }

    public virtual Member Member { get; set; }
    public virtual Comment Comment { get; set; }

    public int Something { get; set; }
    public string SomethingElse { get; set; }
}

如您所见,它实际上允许您拥有重复的 MemberComments(连接相同的 Member 和 Comment 实例)。

如果你想强制MemberComment只能链接一次,那么你可以用Unique Constraint来实现。

但如果这是您的要求(每个成员评论对一个 MemberComment),那么您为什么要添加 MemberCommentID 键?

MemberID, CommentID 是一个 完美而自然的主键 ,无需额外 fields/indices.

即可完成所有工作