Entity Framework Code First和连接字符串

6

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

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

我把参数Database=改成了'2'并保存。

Journal.mdf文件被创建成功,程序也恢复正常运行。如果我再次尝试重命名任何数据库名称,就会遇到“无法打开”的错误。

为什么每次更改模型都需要提供独特的数据库名称?如何“清理”以前的名称?


你在删除数据库后是否正在重新启动应用程序? - StriplingWarrior
@StriplingWarrior:是的,我是。我在再次启动应用程序时遇到了错误。 - Eric J.
1个回答

6
当创建模型时,不需要每次都使用唯一的数据库名称。首次创建模型时会运行DatabaseInitializer执行一些操作,例如如果不存在则创建数据库或添加种子数据。默认的DatabaseInitializer尝试将使用模型所需的数据库架构与在创建数据库(当使用Code First创建数据库时)时创建的EdmMetadata表中存储的架构哈希进行比较。如果哈希比较不同,则抛出该错误。
显然,如果更改连接字符串,则将创建一个全新的名为'MyJournal2'的数据库。
解决此问题的方法是删除EdmMetadata表并重新运行初始化程序。您可以通过进入Visual Studio中的Database Explorer窗口并连接到您的数据库,然后转到Tables,在那里您应该找到EdmMetadata表,右键单击它并选择Delete来执行此操作。
或者将
DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<dbType>());

在Global.asax.cs的Application_Start方法中,这将在模式更改时删除数据库并重新创建它。
请参见Pluralsight上的此视频,特别是部分“当类变化时”。
另请查看此链接DropCreateDatabaseIfModelChanges。 它告诉您实际发生的情况以及如何通过创建派生类来提供数据库。

当我删除.mdf文件时,为什么会出现“权限被拒绝”的错误?如果已删除.mdf文件,EdmMetadata表在哪里? - Eric J.
我已经更新了关于如何删除EdmMetadata表的答案。我强烈建议您观看我提供链接的视频,它会告诉您所有需要知道的内容。您可能会因为多种原因而收到“权限被拒绝”的错误消息,其中之一是Web服务器仍在运行并访问该数据库。 - dnatoli
经进一步检查,我发现您只是删除了文件而不是数据库本身。通过删除 .mdf 和 .ldf 文件,您只是删除了数据和日志文件。有关数据库及其文件位置的信息存储在 SQL Server 主数据库中,因此您需要通过数据库资源管理器或 SQL Server/Express 管理工具从中删除它。 - dnatoli
我在SQL Server Management Studio中没有看到“Journal”数据库的任何提及。我在Object Explorer的Databases节点和sys.Databases中查找过了。 - Eric J.
嗯,那就不确定了。你说在删除.mdf文件时出现了权限被拒绝的错误吗?你尝试过放置SetInitializer调用了吗? - dnatoli
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接