如何检查数据库架构是否与实体框架架构匹配?

Edu*_*tes 10 entity-framework initializer database-schema ef-code-first

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

context.Database.Initialize(true)
Run Code Online (Sandbox Code Playgroud)

如果架构与我的代码第一个架构不匹配,则不会抛出异常.

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

Axd*_*der 17

您可以调用CompatibleWithModel来确定数据库是否与模型匹配.如果将参数设置为true,则在数据库中未找到模型数据时将引发异常.

bool isCompatible = context.Database.CompatibleWithModel(true);
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,这似乎在EF Core中被删除:\有没有人知道EF Core中的替代品? (6认同)
  • 请注意,我尝试在数据库优先应用程序上使用它,它只能与代码优先数据库一起使用。不过还是谢谢你。 (2认同)

Paw*_*wel 7

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

  • 如果您既不更改模型也不更改数据库,并且之前它们匹配,那么您可能不需要这样做.我认为无论您使用哪种访问技术,这个问题都存在,开发过程应该处理这个问题.在运行时重新发现数据库对我来说似乎是一种错误的方法. (3认同)
  • @Pawel,您似乎还没有发货!客户安装产品1.0,然后更新它,这需要更改数据库。然后,客户安装新代码,但由于某种原因而无法(无论出于何种原因)无法正确更新架构-然后他们运行该产品,并且当代码尝试从缺少的列中读取时,您会收到一个令人讨厌的异常。因此,最好先检查一下,或者至少尝试进行一些验证,以便弹出更好的错误消息然后退出。 (3认同)
  • @Pawel 该框架确实应该处理这种检查,因为它拥有所有这些信息可用于与 EDMX 中的数据库进行比较。我还认为,由多个在运行时加载的 DLL 组成的应用程序应该在尝试使用它们之前检查它们是否存在;一个“FileNotFoundException”,其中解释了缺少什么文件以及从哪里获取它,这比由于找不到文件和代码继续执行而导致的“NullReferenceException”有用得多。 (2认同)

Jam*_*oux 5

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

开发人员的解释:https ://www.thereformedprogrammer.net/ef-core-take-full-control-of-the-database-schema/

正如您将看到的,开发人员自己的解释包括对代码优先、数据库优先和 SQL 优先方法的全面概述。他讨论了所有方法的优缺点。并说明为什么架构比较工具对于使用 SQL 优先方法是必要的。

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

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

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