【问题标题】:Extension available for ConfigurationDbContext in identityserver4?identityserver4 中的 ConfigurationDbContext 可用扩展?
【发布时间】:2019-07-09 13:44:48
【问题描述】:

是否有任何可用于 ConfigurationDbContext 的扩展,我们可以在使用 IdentityServer4 时为任何其他字段或索引自定义上下文?

是否可以扩展 IdentityServer4 提供的模型?

【问题讨论】:

    标签: identityserver4


    【解决方案1】:

    我猜你问的是如何自定义 EntityFramework.DbContexts.Config

    你可以从下面的代码中得到一些想法

    public class CustomConfigurationContextFactory : IDbContextFactory<CustomConfigurationDbContext>
    {
        /// <summary>
        /// A factory to create an instance of the StudentsContext 
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        public static CustomConfigurationDbContext Create(string connectionString)
        {
            var optionsBuilder = new DbContextOptionsBuilder<ConfigurationDbContext>();
    
            optionsBuilder.UseSqlServer(connectionString);
    
            var context = new CustomConfigurationDbContext(
                optionsBuilder.Options, 
                new ConfigurationStoreOptions());
            context.Database.EnsureCreated();
    
            return context;
        }
    
        public CustomConfigurationDbContext Create(DbContextFactoryOptions options)
        {
            var context = new CustomConfigurationDbContext(
                new DbContextOptions<ConfigurationDbContext>(),
                new ConfigurationStoreOptions() 
              );
    
            context.Database.EnsureCreated();
    
            return context;
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.ConfigureClientContext(_storeOptions);
            builder.Entity<Client>().HasIndex(x => x.ClientName).IsUnique();
        }
    }
    
    public class CustomConfigurationContextFactory : IDbContextFactory<CustomConfigurationDbContext>
    {
        public CustomConfigurationDbContext Create(DbContextFactoryOptions options)
        {
            var context = new CustomConfigurationDbContext(
                new DbContextOptions<ConfigurationDbContext>(),
                new ConfigurationStoreOptions() 
              );
    
            context.Database.EnsureCreated();
    
            return context;
        }
    }
    

    OnModelCreating您可以添加索引,也可以将您的自定义 Dbset 添加到自定义配置 dbcontext 中

    【讨论】:

      【解决方案2】:

      您可以在 Asp.net Core 中像这样扩展 ConfigurationDbContext 类:

          public class MyNewModel
          {
            public int Id { get; set; }
            public string Name { get; set; }
          }
      
         public class MyOtherNewModel
         {
            public int Id { get; set; }
            public ApiResource ApiResource { get; set; }//<-- This is built-in model for identityserver4.
            public MyNewModel MyNewModel { get; set; }
            public List<ApiClaims> ApiClaims {get; set;} //<-- This will add a "MyOtherNewModelId" field into built-in ApiClaims table.
         }
      
          public class IdentityProviderDbContext : ConfigurationDbContext
          {
            public IdentityProviderDbContext(DbContextOptions<ConfigurationDbContext> options, ConfigurationStoreOptions storeOptions) : base(options, storeOptions)
            { }
      
            public DbSet<MyNewModel> MyNewModelTable { get; set; }
      
            public DbSet<MyOtherNewModel> MyOtherNewModelTable { get; set; }
      
            //...
          }
      

      然后我们可以在控制台中使用以下命令:

      add-migration InitialDeriveFromBaseClass -context IdentityProviderDbContext
      

      您还可以设法在单独的类库中扩展它,如下所示:
      1- 创建一个新的 .net 核心类库。
      2- 像这样更改上面的IdentityProviderDbContext 类:

          public class IdentityProviderDbContext : ConfigurationDbContext
          {
          //TODO: This connecton string will be removed as soon as possible.
          string connectionString = "Server=.;Database=SomeDb;Trusted_Connection=True;MultipleActiveResultSets=true";
      
          public IdentityProviderDbContext(DbContextOptions<ConfigurationDbContext> options)
              : base(options,
                   new ConfigurationStoreOptions()
                   {
                       ConfigureDbContext = configureOptions =>
                          configureOptions.UseSqlServer("Server=.;Database=SomeDb;Trusted_Connection=True;MultipleActiveResultSets=true",
                                                      sql => sql.MigrationsAssembly(typeof(IdentityProviderDbContext).GetTypeInfo().Assembly.GetName().Name))
                   })
          { }
      
          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          {
              optionsBuilder.UseSqlServer(connectionString);
          }
          //...
          // The other parts are the same as above code snippet.
      

      也许我们应该以更合适的方式进行连接字符串(对 SOLID 更友好)。但这只是一个例子。
      3- 添加一个名为IdentityProviderDbContextFactory 的新类,以告知实体框架如何生成迁移。

      class IdentityProviderDbContextFactory : IDesignTimeDbContextFactory<IdentityProviderDbContext>
      {
          public IdentityProviderDbContext CreateDbContext(string[] args)
          {
              var optionsBuilder = new DbContextOptionsBuilder<ConfigurationDbContext>();
              optionsBuilder.UseSqlServer("Server=.;Database=SomeDb;Trusted_Connection=True;MultipleActiveResultSets=true");
      
              return new IdentityProviderDbContext(optionsBuilder.Options);
          }
      }
      

      4- 运行 add-migration 命令
      并完成。

      如果你想在现有的内置模型中添加一个字段,也许你应该阻止 EF 生成original class model(在OnConfiguring() 或某处),而是引入一个derived model(从那个original model )

      【讨论】:

        猜你喜欢
        • 2018-01-16
        • 2019-07-02
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        • 2016-10-24
        • 2019-09-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多