EF Core Mapping EntityTypeConfiguration

后端 未结 15 1233
花落未央
花落未央 2020-11-30 18:26

In EF6 we usually able to use this way to configure the Entity.

public class AccountMap : EntityTypeConfiguration
{
    public AccountMap()
           


        
相关标签:
15条回答
  • 2020-11-30 19:06

    Well here is the issue for the enhancement on the EF7 Github repo: https://github.com/aspnet/EntityFramework/issues/2805

    You can track the issue directly there, altough its is still only in backlog without designated priority.

    0 讨论(0)
  • 2020-11-30 19:08

    Just implement the IEntityTypeConfiguration

    public abstract class EntityTypeConfiguration<TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : class
    {
        public abstract void Configure(EntityTypeBuilder<TEntity> builder);
    }
    

    and then add it to your entity Context

    public class ProductContext : DbContext, IDbContext
    {
        public ProductContext(DbContextOptions<ProductContext> options)
            : base((DbContextOptions)options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new ProductMap());
        }
    
        public DbSet<Entities.Product> Products { get; set; }
    }
    
    0 讨论(0)
  • 2020-11-30 19:10

    In ef core we have to impelement IEntityTypeConfiguration instead of EntityTypeConfiguration in this case we have full access to DbContext modelBuilder and we can use fluent api but in ef core this api is a litle bit diferent from previous versions. you can find more details on ef core model configuration on

    https://www.learnentityframeworkcore.com/configuration/fluent-api

    0 讨论(0)
  • 2020-11-30 19:10

    I have a project that allows you to configure entities outside of the DbContext.OnModelCreating You configure each entity in a seperate class which inherits from StaticDotNet.EntityFrameworkCore.ModelConfiguration.EntityTypeConfiguration

    First you need to create a class which inherits from StaticDotNet.EntityFrameworkCore.ModelConfiguration.EntityTypeConfiguration<TEntity> where TEntity is the class you want to configure.

    using StaticDotNet.EntityFrameworkCore.ModelConfiguration;
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
    
    public class ExampleEntityConfiguration
        : EntityTypeConfiguration<ExampleEntity>
    {
        public override void Configure( EntityTypeBuilder<ExampleEntity> builder )
        {
            //Add configuration just like you do in DbContext.OnModelCreating
        }
    }
    

    Then in your Startup class you just need to tell Entity Framework where to find all of your configuration classes when you are configuring your DbContext.

    using StaticDotNet.EntityFrameworkCore.ModelConfiguration;
    
    public void ConfigureServices(IServiceCollection services)
    {
        Assembly[] assemblies = new Assembly[]
        {
            // Add your assembiles here.
        };
    
        services.AddDbContext<ExampleDbContext>( x => x
            .AddEntityTypeConfigurations( assemblies )
        );
    }
    

    There is also an option for adding type configurations using a provider. The repo has complete documentation on how to use it.

    https://github.com/john-t-white/StaticDotNet.EntityFrameworkCore.ModelConfiguration

    0 讨论(0)
  • 2020-11-30 19:15

    Since EF Core 2.2 you can add all configs (classes, which implemented IEntityTypeConfiguration interface) in one line in the method OnModelCreating in class, which is inherited from DbContext class

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //this will apply configs from separate classes which implemented IEntityTypeConfiguration<T>
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    }
    

    And, as it was mentioned in the previous answer, since EF Core 2.0, you can implement the interface IEntityTypeConfiguration, setup mapping configuration with using FluentAPI in Configure method.

    public class QuestionAnswerConfig : IEntityTypeConfiguration<QuestionAnswer>
    {
        public void Configure(EntityTypeBuilder<QuestionAnswer> builder)
        {
          builder
            .HasKey(bc => new { bc.QuestionId, bc.AnswerId });
          builder
            .HasOne(bc => bc.Question)
            .WithMany(b => b.QuestionAnswers)
            .HasForeignKey(bc => bc.QuestionId);
          builder
            .HasOne(bc => bc.Answer)
            .WithMany(c => c.QuestionAnswers)
            .HasForeignKey(bc => bc.AnswerId);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 19:15

    This is what I am doing in a project I'm currently working on.

    public interface IEntityMappingConfiguration<T> where T : class
    {
        void Map(EntityTypeBuilder<T> builder);
    }
    
    public static class EntityMappingExtensions
    {
         public static ModelBuilder RegisterEntityMapping<TEntity, TMapping>(this ModelBuilder builder) 
            where TMapping : IEntityMappingConfiguration<TEntity> 
            where TEntity : class
        {
            var mapper = (IEntityMappingConfiguration<TEntity>)Activator.CreateInstance(typeof (TMapping));
            mapper.Map(builder.Entity<TEntity>());
            return builder;
        }
    }
    

    Usage:

    In your Context's OnModelCreating method:

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
    
            builder
                .RegisterEntityMapping<Card, CardMapping>()
                .RegisterEntityMapping<User, UserMapping>();
        }
    

    Example mapping class:

    public class UserMapping : IEntityMappingConfiguration<User>
    {
        public void Map(EntityTypeBuilder<User> builder)
        {
            builder.ToTable("User");
            builder.HasKey(m => m.Id);
            builder.Property(m => m.Id).HasColumnName("UserId");
            builder.Property(m => m.FirstName).IsRequired().HasMaxLength(64);
            builder.Property(m => m.LastName).IsRequired().HasMaxLength(64);
            builder.Property(m => m.DateOfBirth);
            builder.Property(m => m.MobileNumber).IsRequired(false);
        }
    }
    

    One other thing I like to do to take advantage of the folding behavior of Visual Studio 2015 is for an Entity called 'User', you name your mapping file 'User.Mapping.cs', Visual Studio will fold the file in the solution explorer so that it is contained under the entity class file.

    0 讨论(0)
提交回复
热议问题