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

SQLite不支持序列的解决方案:EF Core HiLo配置报错处理

问题:SQLite不支持序列导致EF Core报错

使用Entity Framework Core实现代码时,遇到错误提示:SQLite does not support sequences.。移除CatalogTypeEntityTypeConfiguration中的以下代码后错误消失:

//builder.Property(ci => ci.Id)
//    .UseHiLo("catalog_type_hilo")
//    .IsRequired();

请问该如何解决?

解决方案

SQLite本身不支持数据库序列,而UseHiLo依赖序列生成ID,因此触发报错。可以通过以下几种方式适配不同数据库环境:

方法1:按数据库类型动态配置ID生成策略

修改CatalogTypeEntityTypeConfiguration,根据当前数据库提供者选择对应的ID生成方式:

public void Configure(EntityTypeBuilder<CatalogType> builder)
{
    builder.ToTable("CatalogType");
    builder.HasKey(ci => ci.Id);

    // 根据数据库类型切换配置
    if (builder.Metadata.Model.GetDbContextDependencies().DatabaseProvider.Name == "Microsoft.EntityFrameworkCore.Sqlite")
    {
        // SQLite使用自增主键
        builder.Property(ci => ci.Id)
            .ValueGeneratedOnAdd()
            .UseIdentityColumn()
            .IsRequired();
    }
    else
    {
        // 其他支持序列的数据库(如SQL Server)保留HiLo配置
        builder.Property(ci => ci.Id)
            .UseHiLo("catalog_type_hilo")
            .IsRequired();
    }

    builder.Property(cb => cb.Type)
        .IsRequired()
        .HasMaxLength(100);
}

方法2:全局统一适配数据库特性

在CatalogDbContext的OnModelCreating中批量处理所有实体的ID配置:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.ApplyConfiguration(new CatalogTypeEntityTypeConfiguration());

    // 针对SQLite替换所有HiLo配置为自增
    if (Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite")
    {
        foreach (var entityType in builder.Model.GetEntityTypes())
        {
            var primaryKey = entityType.FindPrimaryKey();
            if (primaryKey != null)
            {
                foreach (var property in primaryKey.Properties)
                {
                    if (property.ValueGenerated == ValueGenerated.OnAdd)
                    {
                        property.SetValueGenerated(ValueGenerated.OnAdd);
                        property.UseIdentityColumn();
                    }
                }
            }
        }
    }
}

方法3:仅在测试环境调整配置

如果仅测试用SQLite出现问题,可在测试项目的CatalogDatabaseFixture中覆盖配置:

public CatalogDatabaseFixture()
{
    _connection = new SqliteConnection(InMemConnectionString);
    _connection.Open();
    var options = new DbContextOptionsBuilder<CatalogDbContext>()
        .UseSqlite(_connection)
        .Options;
    CatalogContext = new CatalogDbContext(options);

    // 覆盖CatalogType的ID生成策略为SQLite支持的自增
    CatalogContext.ModelBuilder.Entity<CatalogType>()
        .Property(ci => ci.Id)
        .ValueGeneratedOnAdd()
        .UseIdentityColumn();

    CatalogContext.Database.EnsureCreated();
}
相关代码实现

CatalogType.cs

using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Catalog.Api.Database.Entities
{
    public class CatalogType
    {
        public int Id { get; set; }
        public string Type { get; set; }
    }

    class CatalogTypeEntityTypeConfiguration
    : IEntityTypeConfiguration<CatalogType>
    {
        public void Configure(EntityTypeBuilder<CatalogType> builder)
        {
            builder.ToTable("CatalogType");

            builder.HasKey(ci => ci.Id);

            builder.Property(ci => ci.Id)
                .UseHiLo("catalog_type_hilo")
                .IsRequired();

            builder.Property(cb => cb.Type)
                .IsRequired()
                .HasMaxLength(100);
        }
    }
}

CatalogDbContext.cs

using Catalog.Api.Database.Entities;
using Microsoft.EntityFrameworkCore;

namespace Catalog.Api.Database
{
    public class CatalogDbContext : DbContext
    {
        public CatalogDbContext(DbContextOptions<CatalogDbContext> options) : base(options)
        {
        }

        public DbSet<CatalogType> CatalogTypes { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            builder.ApplyConfiguration(new CatalogTypeEntityTypeConfiguration());
        }
    }
}

CatalogDatabaseFixture.cs

using Catalog.Api.Database;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System.Data.Db;

namespace Catalog.Tests.Unit
{
    public class CatalogDatabaseFixture : IDisposable
    {
        private const string InMemConnectionString = "Data Source=:memory:";
        private DbConnection _connection;
        public CatalogDbContext CatalogContext { get; private set; }

        public CatalogDatabaseFixture()
        {
            _connection = new SqliteConnection(InMemConnectionString);
            _connection.Open();
            var options = new DbContextOptionsBuilder<CatalogDbContext>()
                .UseSqlite(_connection)
                .Options;
            CatalogContext = new CatalogDbContext(options);
            CatalogContext.Database.EnsureCreated();

        }

        public void Dispose()
        {
            if(CatalogContext != null)
            {
                CatalogContext.Dispose();
            }

            if (_connection != null)
            {
                _connection.Dispose();
                _connection = null;
            }
        }
    }
}

CatalogControllerTest.cs

namespace Catalog.Tests.Unit
{
    public class CatalogControllerTest : IClassFixture<CatalogDatabaseFixture>, IDisposable
    {
        private CatalogDatabaseFixture _fixture;
        public CatalogControllerTest(CatalogDatabaseFixture fixture)
        {
            _fixture = fixture;            
        }

        public void Dispose()
        {
            _fixture.CatalogContext.CatalogTypes.RemoveRange(_fixture.CatalogContext.CatalogTypes.AsEnumerable());
            _fixture.CatalogContext.SaveChanges();
        }


        [Fact]
        public void AllAsync_ShouldExist_ControllerAndAction()
        {
            // Given
            var controller = new CatalogController(_fixture.CatalogContext);
            // When
            var response = controller.AllAsync();
        }

        [Fact]
        public void AllAsync_ShouldReturn_ListOfCatalogItems()
        {

        }

    }
}

内容的提问来源于stack exchange,提问作者Tech with Thiru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:12:09