Reputation: 1226
I'm trying to create 2 entities, user and user reviews, where user reviews has a composite primary keys which are the ids of the users, the one who got reviewed and who did it, this composite primary key is also a foreign key to the primary key in the User's table, however EF is creating an extra column that I don't see the point in it, also when I save to the db an User Review object this column doesn't get populated , it's always empty.
This is causing that when I try retrieve an user with its reviews the reviews collection is always empty unless the User_SubjectId column contains the id of the user.
My query is like this
return _context.Users
.Include(u => u.Reviews)
.Where(u => u.SubjectId.Equals(subjectId));
The Reviews collection always is empty
User Review entity
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace API.Data.Entities
{
public class UserReview
{
[Key, Column(Order = 0), ForeignKey("Reviewer")]
public string ReviewerId { get; set; } //The user that wrote the review
[Key, Column(Order = 1), ForeignKey("ReviewedUser")]
public string ReviewedUserId { get; set; } //The user who was reviewed
[Required]
[Range(1, 5)]
public int Rating { get; set; }
[Required]
public DateTimeOffset DateCreated { get; set; }
[Required]
public virtual User Reviewer { get; set; }
[Required]
public virtual User ReviewedUser { get; set; }
}
}
The User entity is like this
public class User
{
[Key]
[Required]
public string SubjectId { get; set; }
public User()
{
Reviews = new List<UserReview>();
}
public virtual ICollection<UserReview> Reviews { get; set; }
}
However when I add the migration another columns gets created in my UserReviews table as shown on this picture, the column is User_SubjectId
I don't know if this is a bug in EF or I did my mapping wrong, in any case any ideas?
Thanks
Upvotes: 1
Views: 3383
Reputation: 2650
You have to use the ReverseProperty annotation.
public class UserReview
{
[Key, Column(Order = 0), ForeignKey("Reviewer")]
public string ReviewerId { get; set; } //The user that wrote the review
[Key, Column(Order = 1), ForeignKey("ReviewedUser")]
public string ReviewedUserId { get; set; } //The user who was reviewed
[Required]
[Range(1, 5)]
public int Rating { get; set; }
[Required]
public DateTimeOffset DateCreated { get; set; }
[Required]
public virtual User Reviewer { get; set; }
[Required)]
public virtual User ReviewedUser { get; set; }
}
public class User
{
[Key]
[Required]
public string SubjectId { get; set; }
public User()
{
Reviews = new List<UserReview>();
}
[InverseProperty("ReviewedUser")] // or Reviewer.
public virtual ICollection<UserReview> Reviews { get; set; }
}
In my opinon, that's the kind of thing that are easier to configure when using fluent mapping.
Upvotes: 2