使用两个外键的导航属性

Navigation Properties using two foreign keys

我有一个项目,在同一个数据库中有多个表。

public class UserImage
{
    [Key]
    public int Id { get; set; }

    public string OwnerId { get; set; }       

    [ForeignKey("OwnerId")]
    public virtual ApplicationUser Owner { get; set; }

    //some fields are removed for brevity
}

public class FriendRequest
{
    [Key]
    public int Id { get; set; }

    public string UserId { get; set; }
    public string FutureFriendUserId { get; set; }

    [ForeignKey("UserId")]
    public virtual ApplicationUser User { get; set; }
    [ForeignKey("FutureFriendUserId")]
    public virtual ApplicationUser FutureFriendUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    //some fields are removed for brevity       
    public virtual ICollection<UserImage> UserImages { get; set; }

    public virtual ICollection<FriendRequest> FriendRequests { get; set; }

问题是我可以找到属于某个用户的图像:

var userStore = new UserStore<ApplicationUser>(db);
var userManager = new UserManager<ApplicationUser>(userStore);

ApplicationUser user = userManager.FindById(User.Identity.GetUserId());

IEnumerable<string> imgs = (from image in user.UserImages select Url.Content(image.ImageUrl)).Skip(skip).Take(5).ToList();

但我不能对 FriendRequests 使用相同的技术。如果我在数据库中搜索具有 UserId == User.Identity.GetUserId() 或其他一些 id 的行,结果就是我所期望的。 有什么问题?

您实际上在这里创建的是一种自我参照的多对多关系。在你的 FriendRequest class 上,你有两个属性是 ApplicationUser 的外键,但在你的 ApplicationUser class 上,你只有一个 FriendRequest。 Entity Framework 不知道哪个外键实际上应该组成这个集合。因此,您必须进行一些更改才能使其正常工作。

  1. 您必须添加另一个导航属性。本质上,在您的 ApplicationUser class 上,您最终会得到如下内容:

    public virtual ICollection<FriendRequest> SentFriendRequests { get; set; }
    public virtual ICollection<FriendRequest> ReceivedFriendRequests { get; set; }
    

    同样,每个外键都需要一个集合。

  2. 您需要添加一些流畅的配置来帮助Entity Framework确定每个集合使用哪个外键:

    public class ApplicationContext : DbContext
    {
        ...
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<FriendRequest>().HasRequired(m => m.User).WithMany(m => m.SentFriendRequests);
            modelBuilder.Entity<FriendRequest>().HasRequired(m => m.FutureFriendUser).WithMany(m => m.ReceivedFriendRequests);
        }