EF Core ValueGeneratedOnAdd 不适用于 postgresql

Pat*_*ryk 2 entity-framework npgsql entity-framework-core asp.net-core-2.0

使用 ConfigurationDbContext 时 Assembly IdentityServer4.EntityFramework.Storage

并用IdentityServer4.Models.Client实体 播种数据库在此处输入图片说明

我收到以下错误:PostgresException:23502:“Id”列中的空值违反了非空约束

我查看了数据库,结果发现该列的类型是integer,尽管我希望它是serial. 在此处输入图片说明

您可以在下面看到负责列创建的部分迁移代码:

 migrationBuilder.CreateTable(
                name: "Clients",
                columns: table => new
                {
                    Id = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Run Code Online (Sandbox Code Playgroud)

modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
Run Code Online (Sandbox Code Playgroud)

此基础上文档https://www.npgsql.org/efcore/value-generation.html,呼吁ValueGeneratedOnAdd()integer列应导致serial数据库类型。

对此有什么想法吗?

Pat*_*ryk 9

改变

.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
Run Code Online (Sandbox Code Playgroud)

.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
Run Code Online (Sandbox Code Playgroud)

已经解决了这个问题。

  • 这是正确的。原始迁移是在 SqlServer 上生成的,因此在 Npgsql 上无法按原样运行。有关与多个提供商合作的更多信息,请参阅 https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/providers。 (2认同)

jjx*_*tra 5

常见提供者的扩展方法。将此代码放置在项目中也包含迁移的任何位置。

namespace MyNamespace;

/// <summary>Entity framework extensions</summary>
public static class EntityFrameworkExtensions
{
    /// <summary>Add identity annotation for sqlite, mysql, postgres and sql server </summary>
    /// <param name="builder">Property builder</param>
    public static void HasIdentityAnnotation<T>(this PropertyBuilder<T> builder)
    {
        builder.HasAnnotation("Sqlite:Autoincrement", true)
        .HasAnnotation("MySql:ValueGeneratedOnAdd", true)
        .HasAnnotation("Npgsql:ValueGenerationStrategy", 
            Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.NpgsqlValueGenerationStrategy.SerialColumn)
        .HasAnnotation("SqlServer:ValueGenerationStrategy", Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.IdentityColumn);
    }
}
Run Code Online (Sandbox Code Playgroud)