Reputation: 553
I have two objects: User and Relationship. A User object is created for each user of my system and multiple relationships will be created for each user depending on how many people they add as friends. The objects look as follows
public class User : IdentityUser {}
public class Relationship {
// User who created the relationship
public User User {get;set;}
// User who the creation user is friends with
public User Friend {get;set;}
// Enum of Status (Approved, Pending, Denied, Blocked)
public RelationshipStatus RelationshipStatus {get;set;}
public DateTime RelationshipCreationDate {get;set;}
}
Each user could have multiple records where they match Relationship.User
and they could have multiple records where they match Relationship.Friend
. I have my DbContext setup as follows in the OnModelCreating
method:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Relationship>(relationship =>
{
relationship.HasOne(r => r.User).WithMany(u => u.Friends);
});
}
I'm new to Entity so this is probably trivial - What am I missing to have the relationship setup as I have described? Thanks!
Edit: To Be more specific, here is the error that I'm getting:
InvalidOperationException: Unable to determine the relationship represented by navigation property 'Relationship.Friend' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'
Edit 2: After rethinking my process, I took a different approach and used the relationships to include followers and following, rather than a collective friends list (fits my business model better anyway). I achieved this with the following:
public class User : IdentityUser {
[InverseProperty("Friend")]
public List<Relationship> Followers {get;set;}
[InverseProperty("User")]
public List<Relationship> Following {get;set;}
}
I am curious if anyone has a solution to the original problem outside of my solution, however, this works for now and seems to fit me best.
Upvotes: 3
Views: 1540
Reputation: 32069
It looks like you are trying to configure many-to-many
with the same entity. To do so, write your User
and Relationship
model classes as follows:
public class User : IdentityUser
{
public List<Relationship> UserFriends { get; set; }
public List<Relationship> FriendUsers { get; set; }
}
public class Relationship {
public string UserId {get; set;} // `UserId` type is string as you are using default identity
public User User {get;set;}
public string FriendId {get; set;}
public User Friend {get;set;}
// Enum of Status (Approved, Pending, Denied, Blocked)
public RelationshipStatus RelationshipStatus {get;set;}
public DateTime RelationshipCreationDate {get;set;}
}
Then in the model builder entity configuration:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Relationship>().HasKey(r => new {r.UserId, r.FriendId});
modelBuilder.Entity<Relationship>()
.HasOne(r => r.User)
.WithMany(u => u.UserFriends)
.HasForeignKey(r => r.UserId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Relationship>()
.HasOne(r => r.Friend)
.WithMany(f => f.FriendUsers)
.HasForeignKey(r => r.FriendId).OnDelete(DeleteBehavior.Restrict);
}
Now it should work properly!
Upvotes: 0
Reputation: 2452
Have you tried adding to the User class a List of Relationships, i.e
public class User : IdentityUser {
List<Relationship> Relationships {get;set;}
}
This might help EF fully understand the relationship.
Upvotes: 1