So, here's what's going on here:
1) There are two classes: Comment
and User
.
2) The third class, Like
, holds references (navigation properties) to both two those classes which correspond to foreign keys in database: UserId
and CommentId
. I explicitly used ForeignKey
attribute, so that it would be clear to you which properties EF will use as foreign keys. In this particular case you could omit this attribute since EF will figure it out automatically (since names match in both classes). Note that it's not mandatory to have foreign keys, but they have advantages.
3) The UserId
and CommentId
comprise composite key. The Column
attribute configures the order of columns in database (so called ordinals). This is important for EF.
4) The User
and Comment
classes also have navigation properties (since it's one
side of one-to-many
relations): Likes
.
5) Finally, always
use Table
attribute to avoid problems with pluralizations because there's no way to turn it off.
[Table("Comment")]
public class Comment
{
public int CommentID { get; set; }
public List<Like> Likes { get; set; }
}
[Table("User")]
public class User
{
public int UserId { get; set; }
public List<Like> Likes { get; set; }
}
[Table("Like")]
public class Like
{
[Key]
[Column(Order = 1)]
public int CommentID { get; set; }
[Key]
[Column(Order = 2)]
public int UserID { get; set; }
[ForeignKey("CommentId")]
public Comment Comment { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
}
UPDATE
Setting composite key in EF Core
The Key
(and Column
) attributes, used to designate composite primary key, actually, don't work in EF Core - they work in EF6. To configure composite key in EF Core, you need to use Fluent Configuration.
You have two options to do it.
OPTION 1. Make all the configuration in OnModelCreatingMethod
:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Like>().HasKey(l => new { l.CommentID, l.UserID });
}
OPTION 2. Move all the configuration into separate class and apply it in OnModelCreating
:
1) Create separate class for configuration
class LikeConfiguration : IEntityTypeConfiguration<Like>
{
public void Configure(EntityTypeBuilder<Like> builder)
{
builder.HasKey(l => new { l.CommentID, l.UserID });
}
}
2) Apply configuration:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new LikeConfiguration());
}
Choose any option you like.
As you see, to configure composite key in Fluent Configuration, you need to use anonymous type. And again, the order of properties matters.