代码之家  ›  专栏  ›  技术社区  ›  WueF

如何在IDesignTimeServices中正确使用IPluralizer

  •  1
  • WueF  · 技术社区  · 7 年前

    在我的应用程序中,我使用代码优先的方法,只通过 IEntityTypeConfiguration<> 我的目标是实现多重表名,即。 模型 模型 .

    读后 documentation , article , This question IPluralizer 在创建迁移期间使用,但不是。

    DbSet<Model> Models {get;set;} 或使用 builder.ToTable("Models"); ,但在我的通用场景中,我希望避免这种情况,特别是我希望一些模型不要覆盖抽象的通用场景。

    问题是,我是做错了什么,还是我误解了它的行为方式

    public class AppDesignService : IDesignTimeServices
    {
        public void ConfigureDesignTimeServices(IServiceCollection services)
        {
            Debugger.Launch();
            services.AddSingleton<IPluralizer, InflectorPluralizer>();
        }
    }
    

    MyDbContext.cs

    public class AppDbContext : IdentityDbContext<AppUser,AppRole,Guid>
    {
        public EmsDbContext(DbContextOptions options) : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
    
            builder.ApplyConfigurationsFromAssembly(Assembly.GetAssembly(typeof(AppDbContext)));
        }
    }
    

    public void ConfigureServices(IServiceCollection services)
    {
        var connectionString = Configuration.GetConnectionString("DefaultConnection");
    
        services.AddDbContext<DbContext, AppDbContext>(opt =>
         {
             opt.UseSqlServer(connectionString, sqlOpt =>
             {
                 sqlOpt.EnableRetryOnFailure(3);
             });
         });
    
         // code skipped for brevity
    }
    

    配置

    public interface IEntity
    {
        int Id {get;set;}
    }
    
    public class Model : IEntity
    {
        public int Id {get;set;}
        public string Name {get;set;}
    }
    
    
    
    public abstract class DbEntityConfig<T> : IEntityTypeConfiguration<T>
        where T : class, IEntity
    {
        public void Configure(EntityTypeBuilder<T> builder)
        {
            builder.HasKey(m => m.Id);
        }
    }
    
    
    public class ModelEntityConfig : DbEntityConfig<Model>
    {
        public void Configure(EntityTypeBuilder<Model> builder)
        {
            base.Configure(builder);
    
            // Of course I want to avoid this call, cos TheOtherModel might not override base method
            // builder.ToTable("Models");
    
            builder.Property(m => m.Name).HasMaxLength(25);
        }
    }
    

    结果

    public partial class Test : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Model",
                columns: table => new
    
                // code skipped for brevity
        }
    }
    

    预期结果:

    public partial class Test : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Models",
                columns: table => new
    
                // code skipped for brevity
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  7
  •   Ivan Stoev    7 年前

    Pluralization hook for DbContext Scaffolding EF核心文件:

    EF Core 2.0引入了一种新的 IPluralizer DbSet

    conventions

    OnModelCreating . 大概是这样的:

    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        entityType.Relational().TableName = GetTableName(entityType);
    

    GetTableName 方法实现您的命名约定:

    string GetTableName(IEntityType entityType)
    {
        // use entiityType.Name and other info
        return ...; 
    } 
    

    更新(EF Core 3.0+): 使用 entityType.SetTableName(...) entityType.Relational().TableName = ...