Search code examples
entity-frameworkef-code-firstfluent-interface

Does Entity Framework Code First allow for fluent mappings in separate files?


I am developing a rather large database schema using Entity Framework Code First. I prefer the Fluent API over the Data Annotations approach, as it leaves my domain objects as simple POCOs.

In order to use Fluent API, I have to override OnModelCreating in the class that inherits from DbContext.

I don't like that all mappings for all of my entities are in this one method. I have used things like FluentNHibernate before, where each entity has it's own mapping class. Does EF have anything similar?

I suppose I could create my own interface to implement a mapping class and call them all within the OnModelCreating method. I could use reflection or an IoC to discover them all. I don't particularly see anything wrong with this approach, but I was wondering if Entity Framework already comes with something like this out of the box?


Solution

  • You can create one configuration class per entity derived from EntityTypeConfiguration<TEntity> and put these classes into separate files. In your derived DbContext you add instances of those configuration classes to the model builder. Example:

    public class UserConfiguration : EntityTypeConfiguration<User>
    {
        public UserConfiguration()
        {
            HasKey(u => u.UserName);
    
            Property(u => u.UserName)
                .HasMaxLength(50)
                .IsRequired();
    
            // etc.
        }
    }
    
    public class RoleConfiguration : EntityTypeConfiguration<Role>
    {
        public RoleConfiguration()
        {
            HasKey(r => r.RoleName);
    
            // etc.
        }
    }
    

    Derived context:

    public class MyContext : DbContext
    {
        //...
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new UserConfiguration());
            modelBuilder.Configurations.Add(new RoleConfiguration());
        }
    }
    

    There is also a ComplexTypeConfiguration<T> you can derive from to configure complex types.