【问题标题】:How to check if database schema matches Entity Framework schema?如何检查数据库架构是否与实体框架架构匹配?
【发布时间】:2012-10-26 15:02:43
【问题描述】:

令我惊讶的是,使用 CreateDatabaseIfNotExists 上下文初始化程序,行

context.Database.Initialize(true)
如果架构与我的代码优先架构不匹配,

不会抛出异常。

有没有办法验证当前数据库是否与我们的架构匹配,例如,我们尝试访问一个实体,其表不再存在于数据库中,并且 EF 抛出异常?

【问题讨论】:

标签: entity-framework ef-code-first database-schema initializer


【解决方案1】:

您可以调用 CompatibleWithModel 来确定数据库是否与模型匹配。如果将参数设置为true,如果在数据库中没有找到模型数据,则会抛出异常。

bool isCompatible = context.Database.CompatibleWithModel(true);

【讨论】:

  • 如果抛出异常是什么类型?
  • 我已经检查了 EF 内部,如果数据库中没有元数据,似乎 NotSupportedException 会被抛出。
  • 作为说明,我尝试在数据库优先的应用程序上使用它,它只能与代码优先的数据库一起使用。不过,谢谢。
  • 代码优先实际上意味着“仅代码”。您不能手动更改数据库,除非您为每次更改添加迁移 - 这可以是手动 SQL 或 DBA 提供的脚本。您不能指望 EF 将实际的实时数据库模式与模型进行比较。
  • 仅供参考,这似乎已在 EF Core 中删除:\ 有人知道 EF Core 中的替代品吗?
【解决方案2】:

EF 不会在您每次启动应用程序时交叉检查数据库架构和模型。相反,它正在寻找保存到数据库(__MigrationsHistory 表和 EdmMetadata 之前)的模型,并将这个保存的模型与您正在使用的模型进行比较。如果模型匹配,则将使用数据库。如果模型不匹配,则会抛出异常。如果您的数据库中既没有 __MigrationHistory 也没有 EdmMetadata 表,EF 将假定您使用 DbContext 的数据库优先方法,并且您的数据库与模型匹配。如果您想将数据库与您的模型进行比较,您可以为您的模型转储 Edmx(使用 EdmxWriter.WriteEdmx)并使用 Visual Studio 和 EF 设计器从数据库中获取 Edmx 并比较 SSDL 部分。

【讨论】:

  • "EF 将假定您使用 DbContext 的数据库优先方法,并且您的数据库与模型匹配"。所以每次我的应用程序启动时,我都必须检查数据库中是否存在所有表和所有列?
  • 如果您既不更改模型也不更改数据库并且它们之前匹配,那么您可能不需要这样做。我认为无论您使用哪种访问技术,都存在这个问题,开发过程应该注意这一点。在运行时重新发现数据库对我来说似乎是一种错误的方法。
  • @Pawel 你没有;那时似乎还没有发货!客户安装产品 1.0,然后您对其进行更新,这需要更改数据库。客户然后安装新代码,但未能(无论出于何种原因)正确更新架构 - 然后他们运行产品,当代码尝试从丢失的列中读取时,您会遇到一个令人讨厌的异常。所以最好先检查一下,或者至少尝试一些验证,以便弹出更好的错误消息然后退出。
  • 如果您的应用程序包含多个 dll,您会在每次启动应用程序之前检查它们是否都存在吗?无论出于何种原因,当您部署应用程序时,其中一个可能会丢失,您将得到一个令人讨厌的异常。你所描述的在我看来是一种类似的情况——你没有正确安装你的应用程序。正确安装应用程序后(即所有 dll 都已就位并且数据库已正确更新)是否缺少检查问题?实际上——你将如何处理这样的支票?如果更改了列类型怎么办?长度?指数?新表?
  • @Pawel 该框架确实应该处理这种检查,因为它具有所有这些信息可用于与 EDMX 中的数据库进行比较。我还认为,由在运行时加载的多个 DLL 组成的应用程序应该在尝试使用它们之前检查它们是否存在; FileNotFoundException 说明缺少什么文件以及在哪里获取它比 NullReferenceException 更有用,因为找不到文件并且代码继续执行。
【解决方案3】:

有两种工具可以做到这一点。第一个很受欢迎并且高度发达:

开发者解释:https://www.thereformedprogrammer.net/ef-core-taking-full-control-of-the-database-schema/

如您所见,开发人员自己的解释包括对 Code-First、Database-First 和 SQL-First 方法的全面概述。他讨论了所有方法的优缺点。并说明为什么架构比较工具对于使用 SQL-First 方法是必要的。

github 项目:https://github.com/JonPSmith/EfCore.TestSupport/wiki/9.-EfSchemaCompare

上面的另一位评论员提到了一个鲜为人知的第二个: https://github.com/reckface/EntityFramework.Verify

第二位开发人员还建议使用 DbUp,它提供了一篇哲学文章,我认为值得一读,说明为什么“Microsofty”代码优先和 db-first 方法存在问题,以及为什么将数据库更改为状态的想法系统可以说是一个糟糕的选择。 https://dbup.readthedocs.io/en/latest/philosophy-behind-dbup/

【讨论】:

    猜你喜欢
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2014-07-17
    • 2014-05-25
    • 2011-09-13
    • 2019-11-27
    相关资源
    最近更新 更多