SQLite EF Core 数据库提供程序限制

SQLite 提供程序存在大量迁移限制。 其中大多数限制源自底层 SQLite 数据库引擎中存在的限制,并不特定于 EF。

建模限制

公共关系库(由 Entity Framework 关系数据库提供程序共享)定义 API,用于建模大多数关系数据库引擎所通用的概念。 SQLite 提供程序不支持其中的数个概念。

  • 架构
  • 序列

查询限制

SQLite 本身不支持以下数据类型。 EF Core 可以读取和写入这些类型的值,并且还支持查询相等性 (where e.Property == value)。 但对比和排序等其他操作需要对客户端进行评估。

  • DateTimeOffset
  • 十进制
  • TimeSpan
  • UInt64

建议使用 DateTime 值,而不是 DateTimeOffset。 处理多个时区时,建议将值转换为 UTC 再保存,然后转换回适当的时区。

Decimal 类型的准确度高。 但如果不需要该级别的准确度,建议改用 double。 可以使用值转换器继续在类中使用十进制。

modelBuilder.Entity<MyEntity>()
    .Property(e => e.DecimalProperty)
    .HasConversion<double>();

迁移限制

SQLite 数据库引擎不支持大多数其他关系数据库所支持的许多架构操作。 如果尝试在 SQLite 数据库进行某一种不受支持的操作,则会引发 NotSupportedException

为执行某些操作,请尝试重新构建。 仅 EF Core 模型中的数据库项目可以进行重新构建。 如果数据库项目不属于模型,例如,如果项目是在迁移期间手动创建的,则仍会引发 NotSupportedException

Operation 是否支持?
AddCheckConstraint ✔(重新构建)
AddColumn
AddForeignKey ✔(重新构建)
AddPrimaryKey ✔(重新构建)
AddUniqueConstraint ✔(重新构建)
AlterColumn ✔(重新构建)
CreateIndex
CreateTable
DropCheckConstraint ✔(重新构建)
DropColumn ✔(重新构建)
DropForeignKey ✔(重新构建)
DropIndex
DropPrimaryKey ✔(重新构建)
DropTable
DropUniqueConstraint ✔(重新构建)
RenameColumn
RenameIndex ✔(重新构建)
RenameTable
EnsureSchema ✔(无操作)
DropSchema ✔(无操作)
插入
更新
删除

迁移限制解决方法

可以通过在迁移时手动编写代码来重新构建,从而解决其中部分限制。 表重新构建包括创建新表、将数据复制到新表、删除旧表和重命名新表。 你将需要使用 Sql(string) 方法来执行其中部分步骤。

有关详细信息,请参阅 SQLite 文档中的更改其他类型的表架构

幂等脚本限制

与其他数据库不同,SQLite 不包含过程式语言。 因此,无法生成幂等迁移脚本所需的 if-then 逻辑。

如果了解在数据库中进行的上一次迁移,则可以生成从该迁移到最新迁移的脚本。

dotnet ef migrations script CurrentMigration

否则,建议使用 dotnet ef database update 来进行迁移。 可以在运行命令时指定数据库文件。

dotnet ef database update --connection "Data Source=My.db"

另请参阅