实体框架代码优先和连接字符串

时间:2011-11-23 22:26:03

标签: entity-framework-4 ef-code-first

我有一个使用Entity Framework Code First的小型MVC 3应用程序,并使用此连接字符串作为模型:

data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|Journal.mdf;User Instance=true;Database=MyJournal

当我对模型进行更改(例如添加属性)时,我得到了预期的

  

自创建数据库以来,支持'JournalContext'上下文的模型已发生变化。

因此,在开发模式下,我继续删除Journal.mdf和Journal.ldf。

现在当我再次运行应用程序时,我得到了

  

无法打开登录请求的数据库“MyJournal”。登录   失败。

如果我将连接字符串更改为

data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|Journal.mdf;User Instance=true;Database=MyJournal2

(通过附加'2'更改了Database=参数)

创建了Journal.mdf并且应用程序再次运行。如果我进行了一些更改并尝试再次“回收”任何数据库名称,则会出现“无法打开”错误。

为什么每次更改模型时都需要提供唯一的数据库名称,以及如何“清除”以前的名称?

1 个答案:

答案 0 :(得分:6)

每次都不需要唯一的数据库名称。首次创建模型时,它会运行DatabaseInitializer来执行创建数据库(如果数据库不存在)或添加种子数据等操作。默认的DatabaseInitializer尝试将使用模型所需的数据库模式与存储在使用数据库创建的EdmMetadata表中的模式的哈希进行比较(当Code First是创建数据库的模式时)。如果哈希比较不同,则抛出该错误。

显然,如果您更改连接字符串,那么它将创建一个名为“MyJournal2”的全新数据库。

解决此问题的方法是删除EdmMetadata表并再次运行初始化程序。您可以通过进入Visual Studio中的Database Explorer窗口并连接到数据库,然后转到Tables,找到EdmMetadata表,右键单击它并选择Delete。

或者放

DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<dbType>());

在Global.asax.cs中的Application_Start方法中。这将删除数据库并在架构更改时重新创建它。

有关详细信息,请参阅this video on pluralsight,尤其是“课程更改时”部分。

同时查看DropCreateDatabaseIfModelChanges的此链接。它告诉您实际发生了什么以及如何在需要时通过创建派生类来为数据库设定种子。