7

对于我惊讶的是,使用CreateDatabaseIfNotExists背景初始化,行如何检查数据库模式是否与实体框架模式匹配?

context.Database.Initialize(true) 

抛出一个异常,如果方案不匹配我的代码第一个架构。

有没有一种方法来验证当前数据库是否与我们的模式匹配,例如,我们试图访问一个实体,该实体的表不再存在于数据库中,并且EF引发异常?

+1

现在https://github.com/reckface/EntityFramework.Verify有通过[@reckface(https://stackoverflow.com/users/474702)用于此目的 – user326608

+1

现在好了总比不!太糟糕了,我不再使用EF了:) –

回答

13

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

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

如果抛出的异常是什么类型? – Jerther

+0

我检查过EF内部结构,看起来NotSupportedException将在数据库中没有元数据的情况下进行处理。 – Alexander

+0

作为一个说明,我试图在数据库优先的应用程序上使用它,它只能用于代码优先数据库。不过谢谢你。 –

6

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

+0

“EF会假定你正在使用DbContext的数据库优先方法,并且你的数据库与模型匹配”。所以每次我的应用程序启动时,我都必须检查数据库中是否存在所有表和所有列? –

+1

如果您既不更改模型也不更改数据库,并且它们之前匹配,那么您可能不需要执行此操作。我认为,无论使用哪种接入技术,您都会使用这个问题,并且开发过程应该考虑到这一点。在运行时重新发现数据库对我来说似乎是一个错误的方法。 – Pawel

+1

@Pawel你似乎没有发货!客户安装产品1.0,然后更新它,这需要更改数据库。然后,客户安装新代码,但无法正确更新模式(无论出于何种原因),然后运行该产品,并在代码尝试从缺少的列中读取时收到令人厌恶的异常。所以最好先检查一下,或者至少尝试一下验证,这样你可以弹出一个更好的错误信息,然后退出。 – gbjbaanb