question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Model configuration: Entity type configuration can be factored into a class

See original GitHub issue

Edited by @rowanmiller Oct-13-2016

EntityTypeConfiguration<T> is a feature in EF6.x that allows you to encapsulate the configuration for an entity type in a class.

Here is some code you can use to enable the pattern until we add support in EF Core.

using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Microsoft.EntityFrameworkCore
{
    public abstract class EntityTypeConfiguration<TEntity>
        where TEntity : class
    {
        public abstract void Map(EntityTypeBuilder<TEntity> builder);
    }

    public static class ModelBuilderExtensions
    {
        public static void AddConfiguration<TEntity>(this ModelBuilder modelBuilder, EntityTypeConfiguration<TEntity> configuration)
            where TEntity : class
        {
            configuration.Map(modelBuilder.Entity<TEntity>());
        }
    }
}

And here is a sample application that uses these types:

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

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new BloggingContext())
            {
                db.Database.EnsureCreated();
            }
        }
    }

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Demo;Trusted_Connection=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.AddConfiguration(new BlogMap());
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
    }

    public class BlogMap : EntityTypeConfiguration<Blog>
    {
        public override void Map(EntityTypeBuilder<Blog> builder)
        {
            builder.ToTable("tbl_blogs");

            builder.Property(b => b.Name)
                .IsRequired()
                .HasMaxLength(200);

            builder.Property(b => b.Url)
                .IsRequired()
                .HasMaxLength(500);

            builder.HasIndex(b => b.Url);
        }
    }
}

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:19
  • Comments:45 (20 by maintainers)

github_iconTop GitHub Comments

40reactions
domenkoglercommented, May 11, 2016
    public interface IEntityMappingConfiguration
    {
        void Map(ModelBuilder b);
    }

    public interface IEntityMappingConfiguration<T> : IEntityMappingConfiguration where T : class
    {
        void Map(EntityTypeBuilder<T> builder);
    }

    public abstract class EntityMappingConfiguration<T> : IEntityMappingConfiguration<T> where T : class
    {
        public abstract void Map(EntityTypeBuilder<T> b);

        public void Map(ModelBuilder b)
        {
            Map(b.Entity<T>());
        }
    }

    public static class ModelBuilderExtenions
    {
        private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
        {
            return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
        }

        public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
        {
            var mappingTypes = assembly.GetMappingTypes(typeof (IEntityMappingConfiguration<>));
            foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>())
            {
                config.Map(modelBuilder);
            }
        }
    }

Use:

    public class PersonConfiguration : EntityMappingConfiguration<Person>
    {
        public override void Map(EntityTypeBuilder<Person> b)
        {
            b.ToTable("Person", "HumanResources")
                .HasKey(p => p.PersonID);

            b.Property(p => p.FirstName).HasMaxLength(50).IsRequired();
            b.Property(p => p.MiddleName).HasMaxLength(50);
            b.Property(p => p.LastName).HasMaxLength(50).IsRequired();
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.AddEntityConfigurationsFromAssembly(GetType().Assembly);
    }
5reactions
mmillicancommented, Aug 13, 2015

I’m glad I’m not the only one. I rely on it heavily.

I’ve actually started a solution that I can probably contribute back.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating and Configuring a Model - EF Core
Overview of creating and configuring a Entity Framework Core model via Fluent API, Data Annotations and conventions.
Read more >
IEntityTypeConfiguration<TEntity> Interface
Allows configuration for an entity type to be factored into a separate class, rather than in-line in OnModelCreating(ModelBuilder). Implement this interface ...
Read more >
Organizing Fluent Configurations into Separate Classes in ...
As you know, there is no EntityTypeConfiguration class for organizing fluent configuration classes in Entity Framework Core 1.0, ...
Read more >
Move Fluent API Configurations to Seperate Class in Code ...
Learn how to create seperate configuration class that contains all the configuration specific to an entity in Entity Framework 6 code-first approach.
Read more >
Create an entity type
Entity types enable you to find and create new entities that match a set of filter conditions. You can create a hierarchy of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found