EFCore Tutorial P4:Cleaning Up `OnModelCreating`

As your Entity Framework Core model grows, managing the configuration logic in the OnModelCreating method can become challenging. To keep the code clean, maintainable, and scalable, it’s important to modularize the entity configurations. In this articl…


This content originally appeared on DEV Community and was authored by mohamed Tayel

As your Entity Framework Core model grows, managing the configuration logic in the OnModelCreating method can become challenging. To keep the code clean, maintainable, and scalable, it’s important to modularize the entity configurations. In this article, we’ll explore three approaches to clean up the configuration logic in OnModelCreating:

  1. Using IEntityTypeConfiguration for the Product entity
  2. Using Extension Methods for the Category entity
  3. Using Partial Classes for the ProductSupplier entity

1. Using IEntityTypeConfiguration for Product

IEntityTypeConfiguration is a great way to modularize the configuration logic for each entity into its own class. Let’s see how we can use this approach to configure the Product entity.

Step 1: Create the ProductConfiguration Class

Create a new class ProductConfiguration.cs to configure the Product entity separately:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
    public void Configure(EntityTypeBuilder<Product> builder)
    {
        // Configure properties
        builder.Property(p => p.Name)
               .HasField("_name"); // Use backing field for Name

        builder.Property(p => p.Price)
               .HasColumnType("decimal(18,2)");



        // One-to-One relationship with Inventory
        builder.HasOne(p => p.Inventory)
               .WithOne(i => i.Product)
               .HasForeignKey<Inventory>(i => i.ProductId);


    }
}

Step 2: Apply Configuration in AppDbContext

In AppDbContext, use ApplyConfiguration to apply the Product configuration:

public class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Inventory> Inventories { get; set; }
    public DbSet<Supplier> Suppliers { get; set; }
    public DbSet<ProductSupplier> ProductSuppliers { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply Product configuration using IEntityTypeConfiguration
        modelBuilder.ApplyConfiguration(new ProductConfiguration());
    }
}

This approach separates the Product configuration logic, making the AppDbContext cleaner and easier to maintain.

2. Using Extension Methods for Category

Using extension methods is another great way to modularize configuration logic for an entity. Let’s apply this approach to the Category entity.

Step 1: Create Extension Method

Create an extension method to configure the Category entity in a new file called ModelBuilderExtensions.cs:

public static class ModelBuilderExtensions
{
    public static void ConfigureCategory(this ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Category>(entity =>
        {
            entity.HasKey(c => c.Id);
            entity.Property(c => c.Name).IsRequired().HasMaxLength(50);

            // One-to-Many relationship with Products
            entity.HasMany(c => c.Products)
                  .WithOne(p => p.Category)
                  .HasForeignKey(p => p.CategoryId);
        });
    }
}

Step 2: Apply Extension Method in AppDbContext

In AppDbContext, use the extension method to apply the Category configuration:

public class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Inventory> Inventories { get; set; }
    public DbSet<Supplier> Suppliers { get; set; }
    public DbSet<ProductSupplier> ProductSuppliers { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply Product configuration using IEntityTypeConfiguration
        modelBuilder.ApplyConfiguration(new ProductConfiguration());

        // Apply Category configuration using extension method
        modelBuilder.ConfigureCategory();
    }
}

Using extension methods for the Category configuration makes it easier to extend and maintain your code.

3. Using Partial Classes for ProductSupplier

When you have complex relationships like Many-to-Many configurations, using partial classes allows you to distribute the configuration logic across multiple files, keeping the code modular and clean. Let’s apply this approach to configure the ProductSupplier entity.

Step 1: Create Partial Class for ProductSupplier Configuration

Create a new partial class in a separate file named AppDbContext.ProductSupplierConfiguration.cs to configure the ProductSupplier entity:

public partial class AppDbContext : DbContext
{
    private void ConfigureProductSupplier(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ProductSupplier>()
            .HasKey(ps => ps.Id); // Define primary key for ProductSupplier

        modelBuilder.Entity<ProductSupplier>()
            .HasOne(ps => ps.Product) // Configure the relationship to Product
            .WithMany(p => p.ProductSuppliers)
            .HasForeignKey(ps => ps.ProductId);

        modelBuilder.Entity<ProductSupplier>()
            .HasOne(ps => ps.Supplier) // Configure the relationship to Supplier
            .WithMany(s => s.ProductSuppliers)
            .HasForeignKey(ps => ps.SupplierId);

        modelBuilder.Entity<ProductSupplier>()
            .ToTable("ProductSuppliers"); // Define the table name
    }
}

Step 2: Modify OnModelCreating to Call the Partial Class Method

Now, in the main AppDbContext class, call the ConfigureProductSupplier method in OnModelCreating:

public partial class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Inventory> Inventories { get; set; }
    public DbSet<Supplier> Suppliers { get; set; }
    public DbSet<ProductSupplier> ProductSuppliers { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply Product configuration using IEntityTypeConfiguration
        modelBuilder.ApplyConfiguration(new ProductConfiguration());

        // Apply Category configuration using extension method
        modelBuilder.ConfigureCategory();

        // Apply ProductSupplier configuration using partial class method
        ConfigureProductSupplier(modelBuilder);
    }
}

By splitting the configuration logic for ProductSupplier into a partial class, the code is easier to manage, especially as the number of entities and relationships grows.

Conclusion

By applying these techniques, we achieve a more modular, maintainable, and scalable codebase in Entity Framework Core:

  1. Using IEntityTypeConfiguration for the Product entity ensures that each entity has its configuration class, which improves modularity.
  2. Using Extension Methods for the Category entity provides a flexible way to apply configurations that can be reused across different contexts.
  3. Using Partial Classes for the ProductSupplier entity allows you to split large and complex configurations into smaller, more manageable pieces, keeping the DbContext class clean.

These strategies will help you maintain a cleaner OnModelCreating method and improve the maintainability of your codebase.
Source Code EFCoreDemo


This content originally appeared on DEV Community and was authored by mohamed Tayel


Print Share Comment Cite Upload Translate Updates
APA

mohamed Tayel | Sciencx (2024-09-13T20:49:10+00:00) EFCore Tutorial P4:Cleaning Up `OnModelCreating`. Retrieved from https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/

MLA
" » EFCore Tutorial P4:Cleaning Up `OnModelCreating`." mohamed Tayel | Sciencx - Friday September 13, 2024, https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/
HARVARD
mohamed Tayel | Sciencx Friday September 13, 2024 » EFCore Tutorial P4:Cleaning Up `OnModelCreating`., viewed ,<https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/>
VANCOUVER
mohamed Tayel | Sciencx - » EFCore Tutorial P4:Cleaning Up `OnModelCreating`. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/
CHICAGO
" » EFCore Tutorial P4:Cleaning Up `OnModelCreating`." mohamed Tayel | Sciencx - Accessed . https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/
IEEE
" » EFCore Tutorial P4:Cleaning Up `OnModelCreating`." mohamed Tayel | Sciencx [Online]. Available: https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/. [Accessed: ]
rf:citation
» EFCore Tutorial P4:Cleaning Up `OnModelCreating` | mohamed Tayel | Sciencx | https://www.scien.cx/2024/09/13/efcore-tutorial-p4cleaning-up-onmodelcreating/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.