无法使用 EF Core 在 sqlite 上创建 int-autoincrement 主键

Can't create int-autoincrement primary key on sqlite using EF Core

我正在尝试创建一个简单的 table,其中主键是一个自动递增的整数。 所以我所做的是,创建 .NET class 并尝试创建迁移。

这是 class-实体:

public class PasswordEntry : IEntity<int>
{
    [Key]
    [Column("Id", Order = 0, TypeName = DatabaseType.INT)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Column("Title", Order = 1, TypeName = "nvarchar2(300)")]
    [Required(AllowEmptyStrings = false), MaxLength(300)]
    public string Title { get; set; } = default!;

    [Column("UserName", Order = 2, TypeName = "nvarchar2(2000)")]
    [MaxLength(2000)]
    public string? UserName { get; set; }

    [Column("Password", Order = 3, TypeName = "nvarchar2(4000)")]
    [MaxLength(4000)]
    public string? PasswordHash { get; set; }

    [Column("Url", Order = 4, TypeName = "nvarchar2(5000)")]
    [MaxLength(5000)]
    public string? Url { get; set; }
}

这是上下文:

internal sealed class DatabaseContext : DbContext
{
    public DatabaseContext(string databasePath)
    {
        _dbPath = databasePath;
    }
    
    private readonly string _dbPath;

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite($"Data Source={_dbPath}");

    
    public DbSet<PasswordEntry> PasswordEntries { get; set; } = default!;
}

生成的迁移Up-方法是:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "PasswordEntries",
        columns: table => new
        {
            Id = table.Column<int>(type: "int", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            Title = table.Column<string>(type: "nvarchar2(300)", maxLength: 300, nullable: false),
            UserName = table.Column<string>(type: "nvarchar2(2000)", maxLength: 2000, nullable: true),
            Password = table.Column<string>(type: "nvarchar2(4000)", maxLength: 4000, nullable: true),
            Url = table.Column<string>(type: "nvarchar2(5000)", maxLength: 5000, nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_PasswordEntries", x => x.Id);
        });
}

当我尝试更新数据库时收到错误消息:

Applying migration '20220407093200_AddedPasswordEntryTable'.
Failed executing DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "PasswordEntries" (
    "Id" int NOT NULL CONSTRAINT "PK_PasswordEntries" PRIMARY KEY AUTOINCREMENT,
    "Title" nvarchar2(300) NOT NULL,
    "UserName" nvarchar2(2000) NULL,
    "Password" nvarchar2(4000) NULL,
    "Url" nvarchar2(5000) NULL
);
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY'.
   at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
   at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
SQLite Error 1: 'AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY'.

但是迁移和更新都显示 Id-Column 是一个整数...知道这里可能是什么问题吗?

我认为问题出在您的 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 属性上。删除它或做这样的事情:

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

错误信息:

'AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY' but your type is "int"

正确的sql应该是这样的,(不是整数)

Id = table.Column<integer>(type: "int", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),AUTOINCREMENT,

您不需要在实体 ID 中定义类型。 ef core 会自动识别它是 key,"Integer" 和 Required。

public int Id { get; set; }