What's the simplest approach to friends list in EF?

一曲冷凌霜 提交于 2020-03-16 08:08:13

问题


I would like to create a simple friend list, with each row having two id's (user id and friend id), both referencing "id" field in respective user's profile

|relationId|userId|friendId|

So that users become friends if both sides send a friendship request to eachother. For example:
|1|2|4|
|1|4|2| //users with id 2 and 4 are friends

Setting up a foreign key has been easy for me so far. Things get harder when I have to set up two foreign keys to the same table. I am getting different errors which I look to fix and then re-adjust my code and in the end I feel like I am overcomplicating this.

UserProfile model:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
}

Friends model:

[Table("Friends")]
public class Friends
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int RelationId { get; set; }

    public int UserId { get; set; }

    [ForeignKey("UserId")]
    public UserProfile User { get; set; } // works with one foreign key

    public int FriendId { get; set; }

    [ForeignKey("FriendId")]
    public UserProfile Friend { get; set; } // doesn't work when I add this one
}

This gives me the following exception:

Introducing FOREIGN KEY constraint 'Friends_User' on table 'Friends' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

I have searched for similar problems, I have seen examples with many foreign keys, however, I wasn't able to find any example with two fields linked to the same table.


回答1:


In this case, the exception message tells you that there are multiple foreign keys with cascade actions. This is because with required associations EF implements cascade on delete by default.

So you have to remove at least one cascade action from an association. There is no data annotation for this, so you should use fluent mapping, for instance:

modelBuilder.Entity<Friends>()
            .HasRequired(p => p.User)
            .WithMany()
            .HasForeignKey(p => p.UserId)
            .WillCascadeOnDelete(true);
modelBuilder.Entity<Friends>()
            .HasRequired(p => p.Friend)
            .WithMany()
            .HasForeignKey(p => p.FriendId)
            .WillCascadeOnDelete(false);

(in DbContext's override OnModelCreating).

You don't need the ForeignKey attributes anymore when you use this mapping.



来源:https://stackoverflow.com/questions/20201468/whats-the-simplest-approach-to-friends-list-in-ef

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!