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

ASP.NET Core+SQLite下EF Core种子数据忽略IsActive=0的问题排查

EF Core种子数据中IsActive=0被忽略,SQLite自动设为默认值1

使用ASP.NET Core和SQLite开发银行应用时,向数据库写入种子数据时发现IsActive = 0的设置被EF Core忽略,所有BankAccount实例的IsActive都被设为默认值1。查看生成的SQL日志,发现第二个账户的INSERT语句中完全省略了IsActive字段,导致数据库使用列的默认值。

种子数据代码

modelBuilder.Entity<BankAccount>().HasData(
            new BankAccount {
                PkAccountId = 1,
                FkAccountTypeId = 1,
                Balance = 1500.00M,
                IsActive = 1,
                DateOpened = DateTime.Parse("2024/03/09")
            },
            new BankAccount {
                PkAccountId = 2,
                FkAccountTypeId = 2,
                Balance = 3000.00M,
                IsActive = 0,
                DateOpened = DateTime.Parse("2020/06/01")
            },
            new BankAccount {
                PkAccountId = 3,
                FkAccountTypeId = 3,
                Balance = 8000.00M,
                IsActive = 1,
                DateOpened = DateTime.Parse("2021/01/01")
            },
            new BankAccount {
                PkAccountId = 4,
                FkAccountTypeId = 4,
                Balance = 12000.00M,
                IsActive = 1,
                DateOpened = DateTime.Parse("2024/07/06")
            },
            new BankAccount {
                PkAccountId = 5,
                FkAccountTypeId = 5,
                Balance = 4500.00M,
                IsActive = 1,
                DateOpened = DateTime.Parse("2020/03/08")
            });

生成的SQL日志

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Bank Account" ("PkAccountId", "Balance", "DateOpened", "FkAccountTypeId", "IsActive")
      VALUES (1, '1500.0', '2024-03-09 00:00:00', 1, 1);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Bank Account" ("PkAccountId", "Balance", "DateOpened", "FkAccountTypeId")
      VALUES (2, '3000.0', '2020-06-01 00:00:00', 2);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Bank Account" ("PkAccountId", "Balance", "DateOpened", "FkAccountTypeId", "IsActive")
      VALUES (3, '8000.0', '2021-01-01 00:00:00', 3, 1);
      INSERT INTO "Bank Account" ("PkAccountId", "Balance", "DateOpened", "FkAccountTypeId", "IsActive")
      VALUES (4, '12000.0', '2024-07-06 00:00:00', 4, 1);
      INSERT INTO "Bank Account" ("PkAccountId", "Balance", "DateOpened", "FkAccountTypeId", "IsActive")
      VALUES (5, '4500.0', '2020-03-08 00:00:00', 5, 1);

表创建配置代码

modelBuilder.Entity<BankAccount>(entity =>
        {
            // Table Name
            entity.ToTable("Bank Account");

            // Primary Key
            entity.HasKey(e => e.PkAccountId);
            entity.Property(e => e.PkAccountId).ValueGeneratedOnAdd();

            // Properties
            entity.Property(e => e.DateOpened)
                  .HasColumnType("TEXT")
                  .HasDefaultValue(DateTime.Now)
                  .IsRequired();

            entity.Property(e => e.Balance)
                  .HasColumnType("REAL")
                  .IsRequired();

            entity.Property(e => e.IsActive)
                  .HasColumnType("INTEGER")
                  .HasDefaultValue(1)
                  .IsRequired();

            // Foreign Key Relationship
            entity.HasOne(e => e.BankAccountType)
                  .WithMany(e => e.BankAccounts)
                  .HasForeignKey(e => e.FkAccountTypeId)
                  .OnDelete(DeleteBehavior.Restrict);

        });

问题原因

核心原因是EF Core的HasData逻辑会忽略等于CLR默认值的属性:

  • IsActive是int类型,其CLR默认值为0
  • 当你在种子数据中设置IsActive = 0时,EF Core会认为你没有显式赋值(因为值等于CLR默认值),因此生成INSERT语句时会省略该列
  • 由于表配置中给IsActive设置了HasDefaultValue(1),SQLite会自动使用这个默认值填充该列,最终导致第二个账户的IsActive被设为1

解决方案

方案1:将IsActive改为bool类型(推荐)

bool类型的CLR默认值是false,对应SQLite的0,显式设置false时EF Core会识别为主动赋值,不会忽略该列:

  1. 修改模型属性:
public bool IsActive { get; set; }
  1. 更新表配置:
entity.Property(e => e.IsActive)
      .HasColumnType("INTEGER")
      .HasDefaultValue(true) // 对应原来的默认值1
      .IsRequired();
  1. 调整种子数据:
// 原来的IsActive=1改为true,IsActive=0改为false
new BankAccount {
    PkAccountId = 2,
    FkAccountTypeId = 2,
    Balance = 3000.00M,
    IsActive = false,
    DateOpened = DateTime.Parse("2020/06/01")
}

方案2:使用可空int类型(int?)

将IsActive改为可空int,其CLR默认值为null,显式设置0时EF Core会识别为主动赋值:

  1. 修改模型属性:
public int? IsActive { get; set; }
  1. 表配置可保留原设置(HasDefaultValue(1)依然生效,当值为null时数据库用默认值)
  2. 种子数据无需修改,保持IsActive = 0即可

方案3:禁用EF Core的默认值忽略逻辑(不推荐)

通过配置强制EF Core包含所有属性,即使值等于CLR默认值,但这种方式可能影响其他属性的行为,需谨慎使用:
在表配置中添加:

entity.Property(e => e.IsActive)
      .HasColumnType("INTEGER")
      .HasDefaultValue(1)
      .IsRequired()
      .ValueGeneratedNever(); // 告诉EF该值不会由数据库生成,必须显式提供

注意:此方式会取消数据库的值生成逻辑,所有场景下都需要显式赋值IsActive,否则会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:15:54