AUTOINCREMENT doesn't usually need to be used in SQLite.即使没有此关键字,也可以自动生成ID。
但是,在使用Entity Framework Core(自2.1.3版开始)和SQLite时,整数主键被声明为AUTOINCREMENT。有办法避免这种情况吗?
我尝试将[DatabaseGenerated(DatabaseGeneratedOption.None)]
属性添加到实体的主键属性,但这完全禁用了自动键生成,因此我必须为每个插入手动设置它。否则,EFC尝试使用显式Id = 0
插入。
因此,我需要将其视为在插入时生成的数据库,我只是想避免不必要的AUTOINCREMENT关键字。有没有办法做到这一点?
编辑
这是一些示例C#代码:
using System;
using Microsoft.EntityFrameworkCore;
namespace Experiments
{
public class Entity
{
public long Id { get; set; }
public string Text { get; set; }
}
public class Context : DbContext
{
public DbSet<Entity> Entities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=temp.sqlite");
}
}
public static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
using (var context = new Context())
{
context.Database.EnsureCreated();
}
}
}
}
当使用DB Browser for SQLite进行查看时,这将创建一个如下所示的数据库:
我宁愿没有声明为AUTOINCREMENT的主键,它也会创建sqlite_sequence表。 SQLite可以生成没有该关键字的键,并且它更简单,更快捷。
最佳答案
据我所知,问题是由当前SqliteMigrationsAnnotationProvider
类中的以下代码引起的:
if (property.ValueGenerated == ValueGenerated.OnAdd
&& property.ClrType.UnwrapNullableType().IsInteger()
&& !HasConverter(property))
{
yield return new Annotation(SqliteAnnotationNames.Autoincrement, true);
}
这将
SqliteMigrationsSqlGenerator
类强制为include AUTOINCREMENT
。我不知道为什么会这样,我认为这是一个遗留的错误,但是您最好在他们的问题跟踪器中询问。
查看代码,似乎设置伪造的值转换器将防止这种情况发生,并且可以用作临时解决方法:
modelBuilder.Entity<Entity>()
.Property(e => e.Id)
.HasConversion(v => v, v => v);
关于c# - 如何在EFC和SQLite中避免使用AUTOINCREMENT关键字?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52476810/