Configure One-to-Many relationship using Fluent API in Entity Framework Core

Configure One-to-Many relationship using Fluent API in Entity Framework Core

Entity Framework Core One-to-Many Relationship is established between 2 entities by the use of Fluent APIs. This relationship is configured by the use of Has/With pattern.

The Has side of the pattern has 2 variants which are HasOne() and HasMany() methods. The With side of the pattern has 2 variants which are WithOne() and WithMany() methods. We can use either one from the below 2 Has/With pattern to create a relationship.

  • HasOne – WithMany
  • HasMany – WithOne
Note: Conventions in Entity Framework Core can also be used to create any type of relationships.

Example: Fluent API One-to-Many Relationship

Consider the following Country and City entities.

public class Country
{
    public int Id { get; set; }
 
    public string Name { get; set; }
 
    public ICollection<City> City { get; set; }
}

public class City
{
    public int Id { get; set; }
 
    public string Name { get; set; }
 
    public int FKCountry { get; set; }
 
    public Country Country { get; set; }
}

The Country entity has a Collection Navigation Property called City.

public ICollection<City> City { get; set; }

The City entity has a Reference Navigation Property called Country.

public Country Country { get; set; }

We will create the Entity Framework Core One-to-Many Relationship with Fluent API for these 2 entities by overriding the OnModelCreating method in the Database Context class, as shown below.

public class CountryContext: DbContext
{
    public DbSet<City> City { get; set; }
    public DbSet<Country> Country { get; set; }

    public CountryContext(DbContextOptions<CountryContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //Write Fluent API configurations here

        modelBuilder.Entity<City>()
                    .HasOne(e => e.Country)
                    .WithMany(e => e.City)
                    .HasForeignKey(e => e.FKCountry)
                    .OnDelete(DeleteBehavior.Cascade); ;
    }
}

On performing EF Core Migrations we will get Country and City database tables created having foreign key as FKCountry on the City table.

entity framework core one to many relationship

Understanding One-to-Many Relationship Configuration

  • We can start by configuring any one entity (either Country or City class). Here we start with City entity class by saying modelBuilder.Entity<City>).
  • Next, we use the Has/With pattern, by using the .HasOne(e => e.Country) method, we specified that the city entity contains the reference navigation property of other type “Country”. This creates the one-to-many relationship between them.
  • Next, we move to the other end of the relationship, and by using the .WithMany(e => e.City) method we specified that the Country entity includes collection navigation property of the City type.
  • The .HasForeignKey(e => e.FKCountry) specifies that the property called FKCountry is the foreign key for the City table in the database.
In the above code we have used the HasOne – WithMany pattern to create the One-to-Many Relationship between the City and Country entities.

You can also configure the same One-to-Many Relationship by using the HasMany – WithOne pattern. So in this case we start with Country entity and then create this relationship as shown by the below code:

modelBuilder.Entity<Country>()
            .HasMany(e => e.City)
            .WithOne(e=>e.Country)
            .HasForeignKey(e => e.FKCountry);

Cascade Delete in Fluent API for Foreign Keys

EF Core behaves differently when the parent entity of the foreign key is deleted. We can configure this using Fluent API. We can instruct EF Core to delete the child row from the db table if the related parent row is deleted, or set foreign key to null, or prevent delete.

This is done from .OnDelete() method.

On the below code, we have set DeleteBehaviour as Cascade which means the dependent entity will be deleted when its parent entity is deleted.

modelBuilder.Entity<City>()
            .HasOne(e => e.Country)
            .WithMany(e => e.City)
            .HasForeignKey(e => e.FKCountry)
            .OnDelete(DeleteBehavior.Cascade); //Cascade behaviour

The DeleteBehaviour has 4 values:

  • Cascade : Dependent entities will be deleted if its principal entity is deleted.
  • ClientSetNull: The values of foreign key properties in the dependent entities will be set to null when its parent entity is deleted.
  • Restrict: Prevents Cascade delete.
  • SetNull: The values of foreign key properties in the dependent entities will be set to null when its parent entity is deleted.

Cascade delete Example

We have some names of Cities and Countries in the database tables, as shown by the below image.

cascade delete one to many ef core

Now we will delete Country having an Id ‘1’ from the Country table using the below EF Core code:

Country country = new Country()
{
    Id = 1
};

context.Remove(country);
await context.SaveChangesAsync();

Since the configuration is set for Cascade Delete then all the cities associated with the country having id ‘1’ are also deleted automatically. See the below picture where we have shown the snapshot of the 2 tables after executing the delete. This proves the cascade delete is working properly.

cascade delete one to many entity framework core

Download the source code:

DOWNLOAD

SHARE THIS ARTICLE

  • linkedin
  • reddit
yogihosting

ABOUT THE AUTHOR

I hope you enjoyed reading this tutorial. If it helped you then consider buying a cup of coffee for me. This will help me in writing more such good tutorials for the readers. Thank you. Buy Me A Coffee donate