Cannot create a relationship when using two FK

asp.net asp.net-core entity-framework entity-framework-core

Question

I'm using EF in my ASP.Net Core application and I'm trying to associate an UserNotification table to my User table. These are the tables structure:

public class User : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual UserNotifications { get; set; }
}

public class UserNotifications
{
    public int Id { get; set; }

    [Key, ForeignKey("User")]
    public string UserId { get; set; }
    public User User { get; set; }

    [Key, ForeignKey("Sender")]
    public string SenderId { get; set; }
    public virtual User Sender { get; set; }      

    public string Title { get; set; }
    public string Message { get; set; }
}

What I did is create a ForeignKey of UserNotifications which I'm going to store all the notifications that the User has reiceved.

Inside the table UserNotifications I created two FK for User and Sender. Essentially I want store the Id of the User that has reiceved the notification, and the Id of the User that has sent the notification (Sender).

Inside the OnModelCreating I also defined the following logic:

builder.Entity<UserNotifications>(entity =>
{
    entity.HasKey(n => n.Id);
    entity.HasOne(u => u.User)
          .WithOne(u => u.UserNotifications)
          .HasForeignKey<User>(u => u.Id);

    entity.HasOne(u => u.Sender)
          .WithOne(u => u.UserNotifications)
          .HasForeignKey<User>(u => u.Id);
 });

When I type the following building in the console:

add-migration InitialMigration -context MyAppContext

I get:

Cannot create a relationship between 'User.UserNotifications' and 'UserNotifications.Sender', because there already is a relationship between 'UserNotifications.User' and 'User.UserNotifications'. Navigation properties can only participate in a single relationship.

I'm a newbie of EntityFramework so I don't know how to fix this, someone could explain what I did wrong?

Thanks in advance for any help.

1
4
10/19/2018 7:30:25 PM

Popular Answer

The model you are describing represents two one-to-many relationships between the User and UserNotifications (btw, the entity should be named UserNotification) entities. Each EF relationship can be mapped to 0 or 1 unique navigation properties at each side.

You already have two User and Sender reference navigation properties (and corresponding FKs) in UserNotifications. What you need is two corresponding collection navigation properties in User:

public class User : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<UserNotifications> ReceivedNotifications { get; set; }
    public virtual ICollection<UserNotifications> SentNotifications { get; set; }
}

and map the with fluent API:

builder.Entity<UserNotifications>(entity =>
{
    entity.HasKey(n => n.Id);

    entity.HasOne(n => u.User)
        .WithMany(u => u.ReceivedNotifications)
        .HasForeignKey(n => u.UserId)
        .IsRequired()
        .OnDelete(DeleteBehavior.Delete);

    entity.HasOne(n => n.Sender)
        .WithMany(u => u.SentNotifications)
        .HasForeignKey(n => n.SenderId)
        .IsRequired()
        .OnDelete(DeleteBehavior.Restrict);
 });

Note that since such model introduces the so called multiple cascade paths, you need to turn at least one of the cascade delete off and handle it manually.

9
10/19/2018 7:53:25 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow