Search code examples
c#winformsentity-frameworkcode-firstself-reference

Self relation in C#


I have a class called Person that has an attribute called friends from which is a list of type Person. Actually, I am going to create a many-to-many relationship between the Person class and itself.

How can you create a special table for this relationship in SQL Server using EntityFramework and Codefirst (It is preferable not to use Fluent API)?

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Person> Friends { get; set; }
}

I tried Codefirst, but the table for many-to-many relationships in the SQL Server database was not created. The only thing that happened was creating a column in SQL Server called Person_ID. It seems to create only a one-to-one relationship.

SQL Server Datatable of Person:

ID Name Person_ID
NULL NULL NULL

Solution

  • Remember that there's no first-class way to model a symmetric relationship in a relational database. So if Alice and Bob are friends, you need to store both (Alice,Bob) and (Bob,Alice) in the Friendship table. Otherwise you will find Bob under Alice's friends, but won't find Alice under Bob's friends.

    But to the original question, you collection navigation properties will create 1-many relationships by default. You must configure the entity if you want many-to-many. It's not mandatory to have collection navigation properties for both directions.

    So something like:

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Person> Friends { get; } = new List<Person>();
    }
    

    configured like

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>()
                .HasMany(p => p.Friends)
                .WithMany()
                .UsingEntity(t => t.ToTable("Friendship"));
        }