IdentityServer4带有真实SQL Server的ASP身份示例

时间:2018-05-25 00:11:09

标签: sql-server asp.net-core asp.net-identity entity-framework-core identityserver4

我一直在努力争取最终的SAMPLE(ASP.Net,EF Core,SQL)来对抗真正的SQL Server。我找到的每个样本都不使用真正的SQL,他们总是选择内存数据存储

我更改了连接字符串

"Data Source=.;Initial Catalog=IS4;Integrated Security=True;"

然后跑

dotnet ef database update -c ApplicationDbContext

这为我创建了一个包含25个表的SQL数据库。

我调整了Startup.cs来改变

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(connectionString));

和b.UseSqlite到b.UseSqlServer

            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = b =>
                    b.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            // this adds the operational data from DB (codes, tokens, consents)
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = b =>
                    b.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));

                // this enables automatic token cleanup. this is optional.
                options.EnableTokenCleanup = true;
                // options.TokenCleanupInterval = 15;
            });

我在命令行上使用“/ seed”运行服务器,但种子功能不起作用

首先它抱怨CLIENT在调用SaveChanges()时不能有NULL ID。如果我更改代码以添加ID

        if (!context.Clients.Any())
        {
            Console.WriteLine("Clients being populated");
            int i = 1;
            foreach (var client in Config.GetClients().ToList())
            {
                var x = client.ToEntity();
                x.Id = i++;
                context.Clients.Add(x);
            }
            context.SaveChanges();
        }
        else
        {
            Console.WriteLine("Clients already populated");
        }
然后我得到

"Cannot insert the value NULL into column 'Id', table 'IS4.dbo.ClientGrantTypes".

当我观看视频时,它说它可以简单地通过更改显然不正确的连接字符串从SQLite迁移到完整SQL,考虑到我所做的所有其他更改,所以我必须做(或丢失)某些事情其他

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

可能是所有带有“Id INT”列的表都应该是IDENTITY列而不是它们!

我检查了迁移代码,它有

protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "ApiResources",
                columns: table => new
                {
                    Id = table.Column<int>(nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    Description = table.Column<string>(maxLength: 1000, nullable: true),
                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),

我在猜测

.Annotation("Sqlite:Autoincrement", true),

不适用于完整的SQL,因此所有表都需要设置标识属性。

有趣的是,如果您运行其他模板来添加AdminUI

dotnet new is4admin

似乎添加了几个SQL脚本

CREATE TABLE "Clients" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Clients" PRIMARY KEY AUTOINCREMENT,
    "AbsoluteRefreshTokenLifetime" INTEGER NOT NULL,
    "AccessTokenLifetime" INTEGER NOT NULL,

确实使它们成为标识列。

答案 1 :(得分:0)

为解决此特定问题,我使用了SSMS。

  1. 右键单击表格
  2. 选择要删除并创建的脚本
  3. 在NOT NULL后添加IDENTITY
  4. 执行

不过,您是正确的,它在sql文件和迁移中使用sqlite注释。

要完全解决此问题,您需要创建所有3个必需数据库上下文的实现:身份,持久授权和配置。

这也需要为每个上下文实现设计时工厂。

然后,您可以在程序包管理器控制台中为每个上下文运行add-migration,然后运行更新数据库,或在播种时使用带有迁移功能的应用程序。

所以回顾一下:

  1. 为3个数据库上下文创建实现
  2. 为这些数据库上下文创建设计时工厂实现
  3. 添加迁移
  4. 使用这些迁移更新数据库

答案 2 :(得分:0)

我今天遇到了这个问题,在网上进行了几次搜索,偶然发现了这个https://entityframeworkcore.com/knowledge-base/46587067/ef-core---do-sqlserver-migrations-apply-to-sqlite-

该链接指出了在迁移类 UP 方法之后切换注释部分

Id = table.Column(nullable:false)

来自

.Annotation("Sqlite:Autoincrement", true);

.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)

您将需要导入

使用Microsoft.EntityFrameworkCore.Metadata;

然后构建,迁移将成功。