4

I am using Code First approach while creating Database using Entity Framework Core. I would like to create two foreign keys pointing the same table. My example shows User table which will hold userID and Message table which will hold both Receiver ID and Sender ID (what means both values have to point the same table).

Code for User:

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [MaxLength(50)]
    public string UserName { get; set; }
    [Required]
    [MaxLength(50)]
    public string Password { get; set; }

    public virtual ICollection<Message> MessagesSent { get; set; }
    public virtual ICollection<Message> MessagesReceived { get; set; }
}

For Message:

public class Message
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int id { get; set; }

    public User Sender { get; set; }
    public User Receiver { get; set; }
    public int senderId { get; set; }
    public int receiverId { get; set; }

    [MaxLength(500)]
    public string message { get; set; }

}

I am using ASP.NET Core 2 and I am a newbie. I was trying to use this solution, but unfortunately, I couldn't manage to override OnModelCreating method. It shows that it doesn't exist.

PS. don't mind password field, it is only for testing purpose.

Thank you!

Dawid Stefaniak
  • 347
  • 2
  • 12
  • 1
    Sure there is `OnModelCreating`. Just EF Core method signature is different. So the fluent API. Everything you need is explained in the [Relationships](https://learn.microsoft.com/en-us/ef/core/modeling/relationships) section of the documentation. – Ivan Stoev Mar 11 '18 at 19:02

1 Answers1

6

I managed to make it works using Fluent API.

Code in my DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Message>()
        .HasOne(p => p.Receiver)
        .WithMany(t => t.MessagesReceived)
        .HasForeignKey(m => m.ReceiverId)
        .OnDelete(DeleteBehavior.Restrict);

    modelBuilder.Entity<Message>()
        .HasOne(p => p.Sender)
        .WithMany(t => t.MessagesSent)
        .HasForeignKey(m => m.SenderId)
        .OnDelete(DeleteBehavior.Restrict);                
}

What is more, I've discovered a problem with not set User deletion behaviour. There are two options to solve it.

First is keeping Messages if User was deleted:

.OnDelete(DeleteBehavior.Restrict);

Or second which will remove Messages:

.OnDelete(DeleteBehavior.Cascade);
Dawid Stefaniak
  • 347
  • 2
  • 12
  • 1
    _Or second which will remove Messages_ This doesn't just "remove the message". It actually deletes related data when parent objects are removed. Cascading deletes can be very dangerous for this reason - you may not be aware that other objects are deleted. Be careful with applying this setting. – Yuck Mar 12 '18 at 13:42