【问题标题】:Detect whether model and database out of sync in EF Core 5在 EF Core 5 中检测模型和数据库是否不同步
【发布时间】:2021-11-10 03:26:12
【问题描述】:

我正在使用“创建和删除”APIs,因为我的模型经常更改。

模型更改后,我调用dotnet ef database drop,然后在下一次运行时系统调用context.Database.EnsureCreated() 重新创建数据库。我可以在此之前使用context.Database.EnsureDeleted(),但我不想每次都删除/重新创建数据库(它会减慢“内循环”的开发速度,并且会影响我的驱动器)。

曾经有一种简单的方法(在旧 EF 中)以编程方式检测数据库和模型是否不同步。 EF Core 中没有这样的内置功能。有一些方法(e.g.e.g.),但它们已经使用了几年,不可靠(取决于内部功能)并且适用于旧版本。

v5 中是否有稳定的方法(不使用内部组装功能)来执行此操作?

【问题讨论】:

  • 您可能会根据context.Modelcontext.Model.GetRelationalModel() 编写自己的哈希函数。否则,您必须在某处序列化模型并使用IMigrationsModelDiffer,这会创建迁移步骤。自动迁移是一项常用功能 (github.com/dotnet/efcore/issues/6214)。
  • FYI .EnsureCreated() 如果数据库存在但没有表,将创建 scema。不确定删除所有表是否比删除数据库更快。
  • @JeremyLakeman 这是一个有趣(但费力)的想法。该函数为整个模式返回一个字符串,因此我可以使用直接 sql 调用(ExecuteSqlRaw 或其他任何名称)对其进行哈希处理并将其存储在一个特殊的单字段表中。然后在下次运行比较时,如果有变化,请先调用EnsureDeleted。可能会工作!感谢您的宝贵提示!
  • 实际上,您可能可以散列来自context.Model.DebugView.LongView的字符串
  • 我在context.ChangeTracker.DebugView.LongView 上找到了它。为什么您认为这是更好的选择?

标签: c# entity-framework entity-framework-core ef-core-5.0


【解决方案1】:

您可以让 EF Core 使用 .Model.DebugView.LongView 将您的架构 (context.Model) 序列化为字符串。

然后我会根据该字符串计算一个哈希值,并将该哈希值与存储在表中的值进行比较。

由于 EF Core 不公开运行原始选择查询的方法,尤其是在您不能依赖最新的架构时。您要么需要直接使用SqlConnection 来查询表。

或者将您的比较构建为 insert / update 语句,以便您可以根据受影响的行数决定要做什么。由于您要立即销毁数据库,因此可以忽略该 sql 的副作用。

【讨论】:

  • 如果您使用的是 sql server,您可以将模型哈希存储为扩展属性,而不是存储在表中 (mssqltips.com/sqlservertip/5384/…)
  • 我正在使用 postgres,但我相信这个技巧会帮助很多其他人,谢谢!
  • 谢谢,这个回答对我帮助很大。只有context.Model.DebugView.LongView 不会在ef core 5.0.11 中编译的问题。有效的是((Microsoft.EntityFrameworkCore.Metadata.Internal.Model)context.Model).DebugView.LongView。但请看这里:https://github.com/dotnet/efcore/issues/24434... 获得长调试视图的正确方法是:context.Model.ToDebugString(Microsoft.EntityFrameworkCore.Infrastructure.MetadataDebugStringOptions.LongDefault)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多