如何使用 EF 核心在 SQLite 中创建自动增量列?

Posted

技术标签:

【中文标题】如何使用 EF 核心在 SQLite 中创建自动增量列?【英文标题】:How to create Autoincrement column in SQLite using EF core? 【发布时间】:2018-09-10 13:10:05 【问题描述】:

我首先在我的UWP and .NET Standard 应用程序中使用 Entity Framework Core 2.0 for Sqlite 代码。我的模型有一个主键整数类型的实体,应该根据SQLite documentation 自动递增。但实际上,对于每一行,Identity 列的值都为 0。 请提供帮助,因为我没有找到与此问题相关的帮助材料。

这是我的财产,没有任何数据注释。

public Int32 No get; set;

我用过 fluent API

modelBuilder.Entity<TurnosGeneral>()
            .HasKey(c => new  c.No, c.Cod_Turno );

并在此处插入值

db.TurnosGenerals.Add(new TurnosGeneral  Cod_Turno = numeroTurnoTextBlock.Text );

db.SaveChanges();

对于插入的每一行,c.No 为 0。

【问题讨论】:

【参考方案1】:

我的模型有一个主键整数类型的实体,应该用作自动增量

问题在于,所讨论的属性不是 PK,而是复合PK的一部分,在这种情况下,它不被视为按惯例自动生成,如 EF Core 文档的 Generated Values Conventions 部分所述:

按照惯例,short、int、long 或 Guid 类型的 非复合 主键将设置为在添加时生成值。所有其他属性都将设置为不生成值。

您需要明确指定:

modelBuilder.Entity<TurnosGeneral>()
    .Property(e => e.No)
    .ValueGeneratedOnAdd();

更新:以上是适用于大多数数据库的一般方法。但是 SQLite 支持 AutoIncrement only for column of type INTEGER PRIMARY KEY,因此这不是 EF Core 限制。要么不使用自动增量,要么使其成为非复合 PK。

【讨论】:

我已经尝试过这个并且总是得到一个错误“SqliteException: SQLite Error 19: 'NOT NULL constraint failed:” 这意味着不是自动生成它预期的用户生成的值。毫无疑问,这适用于 EF 6 中的 sql server。 它也适用于 EF Core 2.0.2 中的 SqlServer。在文档中找不到 SQLite 特定要求。 好的,我已经安装了 [SQLite EF Core Database Provider)(docs.microsoft.com/en-us/ef/core/providers/sqlite) 并进行了迁移(注意 Sqlite:Autoincrement):migrationBuilder.CreateTable(name: "TurnosGeneral", columns: table =&gt; new No = table.Column&lt;int&gt;(nullable: false).Annotation("Sqlite:Autoincrement", true), Cod_Turno = table.Column&lt;string&gt;(nullable: false) , constraints: table =&gt; table.PrimaryKey("PK_TurnosGeneral", x =&gt; new x.No, x.Cod_Turno ); ); 但是你是对的,SQLite 提供程序迁移生成器中似乎存在一个错误,它没有考虑到该注释。考虑在他们的问题跟踪器中发布问题。 Annotation("Sqlite:Autoincrement", true) 也未尝试过。顺便说一句,感谢您的 cmets。看来我必须在 github 上为 EF Core for SQLite 创建新问题。【参考方案2】:

看起来像一个错误。检查这个:https://github.com/aspnet/EntityFrameworkCore/issues/11961

我的解决方法:在我的 DBContext 类中的 Id 列上手动更改:.ValueGeneratedNever().ValueGeneratedOnAdd()

【讨论】:

【参考方案3】:

我刚刚使用我用于测试的内存数据库中的 SQLite 遇到了这个问题。就我而言,我有一个带有主键字段的业务类,名为ContactCategoryId

public class ContactCategory

    [Required]
    [Display(Name = "Contact category ID")]
    public int ContactCategoryId  get; set; 

而且我也在使用流利的方法进行设置:

public void Configure(EntityTypeBuilder<ContactCategory> modelBuilder)

    modelBuilder.ToTable("CONTACT_CATEGORY", _schema);

    modelBuilder.HasKey(x => x.ContactCategoryId);

    modelBuilder.Property(x => x.ContactCategoryId)
        .HasColumnName(@"ContactCategoryID")
        //.HasColumnType("int") Weirdly this was upsetting SQLite
        .IsRequired()
        .ValueGeneratedOnAdd()
        ;

注释掉.HasColumnType("int") 的行为我修复了错误。

【讨论】:

对我来说,只有在我完全删除 entity.Property(e => e.Id).HasColumnName("ID");

以上是关于如何使用 EF 核心在 SQLite 中创建自动增量列?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何使用 EF 在 ASP.Net MVC 应用程序中创建 3 层架构?

如何在 sqlite 中创建物化视图?

如何首先在 EF 代码中创建持久计算列?

如何在 SQLite 的插入查询中返回自动增量值?

如何在 xamarin 跨平台应用程序中创建具有 sqlite 支持的 PCL

如何在 phonegap xcode 中创建 sqlite 数据库?