如何使用 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 => new No = table.Column<int>(nullable: false).Annotation("Sqlite:Autoincrement", true), Cod_Turno = table.Column<string>(nullable: false) , constraints: table => table.PrimaryKey("PK_TurnosGeneral", x => 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 层架构?