You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 5.0使用SQLite内存数据库时EnsureCreated报错求助

问题描述

我正在为一个重度依赖Entity Framework Core的C#项目编写单元测试,选用SQLite内存数据库。参考官方示例编写了如下通用初始化类:

初始化类代码

public class SqliteEFCoreContextInitializer<T> : IDisposable where T : DbContext
{
    private SQLiteConnection connection;
    private DbContextOptions<T> contextOptions;
    private Func<DbContextOptions<T>, T> contextInstantationFunction;

    // 通过传入委托绕开无法直接调用泛型T构造函数的问题
    public SqliteEFCoreContextInitializer(Func<DbContextOptions<T>,T> _contextInstantationFunction)
    {
        contextInstantationFunction = _contextInstantationFunction;
        connection = new SQLiteConnection("Data Source=:memory:");

        connection.Open();

        contextOptions = new DbContextOptionsBuilder<T>().UseSqlite(connection).Options;
        using T context = CreateContext();
        context.Database.EnsureCreated();
    }

    public void Dispose()
    {
        connection.Dispose();
    }

    public T CreateContext()
    {
        return contextInstantationFunction(contextOptions);
    }
}

实例化及使用方式

// 实例化初始化器
SqliteEFCoreContextInitializer<MyContext> sqliteContextInitializer = new(options => new MyContext(options));

// 获取SQLite内存DbContext
MyContext context = sqliteContextInitializer.CreateContext();

遇到的错误

执行context.Database.EnsureCreated();时,无论数据库架构如何(哪怕只有一张带整数主键的表),都会抛出错误:

SQL logic error: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY

项目使用的是已过时的EF Core 5.0,不确定是否与此有关,请问问题出在哪里?


解决方案

这个问题确实和EF Core 5.0对SQLite的兼容性有关,核心原因及修复方法如下:

  • 核心问题:EF Core 5.0会给SQLite的整数主键额外添加AUTOINCREMENT约束,但SQLite的规则是:只有当主键类型是INTEGER(注意不是INT或其他整数类型别名)时,才能使用AUTOINCREMENT。EF Core 5.0在生成SQL时,会把实体的int类型主键映射成INT而非INTEGER,导致添加约束时触发错误。

  • 修复方案:

    1. 显式指定主键列类型为INTEGER:在实体配置中,给主键属性指定SQLite的列类型:
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<YourEntity>()
              .Property(e => e.Id)
              .HasColumnType("INTEGER");
      }
      
    2. 禁用AUTOINCREMENT(可选):如果不需要严格的自增序列唯一性(SQLite默认的ROWID已经能实现自增),可以关闭该约束:
      modelBuilder.Entity<YourEntity>()
          .Property(e => e.Id)
          .UseIdentityColumn(autoincrement: false);
      
    3. 升级EF Core版本:如果项目允许,升级到EF Core 6.0及以上版本,官方已修复SQLite自增主键的生成逻辑问题。

内容的提问来源于stack exchange,提问作者Luc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:57:38