所以,我首先尝试EF代码,这样我就可以对数据库进行代码驱动更新。我正在使用ClickOnce开发一个LocalDB应用程序,因此我认为这可能是最好的解决方案,因为否则对MDF文件的更改将导致它在部署时被覆盖在客户端上,从而丢失之前输入的所有内容。
但是,我现在对代码第一迁移方面的所有新问题都有自己的看法。我已经完成了一个MSDN上的代码第一次移动,并且成功地创建了初始的Configuration
,以及初始的数据库创建。
当我试图进行第一次实际迁移时,问题就开始了。我在其中一个模型中添加了一个字段,并试图在下次发布时进行显式迁移以处理模式更改。好吧..。
PM> Add-迁移AddIsPercentField 无法生成显式迁移,因为以下显式迁移挂起: 201601052011180_InitialCreate。在尝试生成新的显式迁移之前应用挂起的显式迁移。
好的..。我将运行更新,然后再试一次:
PM>更新-数据库 指定“详细”标志,以查看应用于目标数据库的SQL语句。 应用显式迁移: 201601052011180_InitialCreate。 应用显式迁移: 201601052011180_InitialCreate。 无法更新数据库以与当前模型匹配,因为有挂起的更改,并且禁用了自动迁移。要么将挂起的模型更改写入基于代码的迁移,要么启用自动迁移。将DbMigrationsConfiguration.AutomaticMigrationsEnabled设置为true以启用自动迁移。 您可以使用“添加迁移”命令将挂起的模型更改写入基于代码的迁移。 PM> Add-迁移AddIsPercentField 无法生成显式迁移,因为以下显式迁移挂起: 201601052011180_InitialCreate。在尝试生成新的显式迁移之前应用挂起的显式迁移。
这很熟悉,因为这就是错误(公然的谎言?)它刚才告诉我了。那么,如果我撤消更改并再次更新,它可能会移动到一个有效的状态:
PM>更新-数据库 指定“详细”标志,以查看应用于目标数据库的SQL语句。 应用显式迁移: 201601052011180_InitialCreate。 应用显式迁移: 201601052011180_InitialCreate。 运行种子法
好吧,这次没有警告。应该是金色的。字段添加回,项目重建。我们开始:
PM> Add-迁移AddIsPercentField 无法生成显式迁移,因为以下显式迁移挂起: 201601052011180_InitialCreate。在尝试生成新的显式迁移之前应用挂起的显式迁移。
所以..。实际上,是否有一种工作方法可以为第一个之外的任何更改生成显式迁移?
编辑:我相信,在这方面取得了一些进展。我确实注意到,__MigrationHistory
表在运行Update-Database
之后没有在.mdf中生成,尽管它说一切都完成得很好。我相信问题实际上是关于本地数据库如何在应用程序中工作。连接字符串引用AttachDbFilename=|DataDirectory|
。我认为正在进行的是临时部署.mdf,更新临时部署,从而最终不提交更改。
我正在研究一个我想到的解决方案,就是让迁移工作针对放在静态位置的空白.mdf的副本,这样静态.mdf将被用于跟踪和确定更改,而空白的.mdf将是部署到客户端的东西。
发布于 2016-01-06 19:59:40
我发现问题的根源在于控制台命令实际上无法对数据文件进行更改,从而跟踪迁移。这是由于引用已部署位置的数据文件的连接字符串造成的,因此所更新的文件只是临时的。
这在一定程度上是一件好事,因为在我的项目中使用的全部目的是避免在发布时对我的.mdf进行散列签名更改(它本来应该是空白的,作为占位符),这样来自以前版本的数据就不会被覆盖和丢弃。然而,这也引入了一个明显的问题(回顾一下),即EF无法跟踪更改,因为从来没有一个__MigrationHistory
表。
我到达的解决方案是有两个.mdf文件。空白的一个用于部署,另一个用于与交互。因此,我获得了最初的构建操作MyData.mdf
Content
,以及构建操作None
的第二个MyDataDesignTime.mdf
。(不应该部署“设计时”迁移数据库。)
使用这种方法,我发现现在可以成功地处理迁移,调用Update-Database
和Add-Migration
,确保使用AttachDbFilename
传递-ConnectionString
参数,指向设计时数据库的完整路径。
后来,由于懒得为每个迁移命令提供一个长的-ConnectionString
参数,我将设计时路径添加到我的配置连接字符串中,并更新了我的DbContext
,以便它最初使用设计时路径,但在运行时开始时会更改它以使用我的实际目标数据文件:
public partial class MyData : DbContext
{
public const string DesignTimeConnection = "MyDataConnectionStringDesignTime";
public static string ConnectionName { get; set; } = DesignTimeConnection;
public MyData()
: base("name=" + ConnectionName)
{
}
...
}
在应用程序初始化时:
MyData.ConnectionName = "MyDataConnectionString";
这很管用,而且让事情变得更简单了。但是,剩下的一个小问题是,我有一个完整的静态路径,它只适用于app.config文件中的环境。目前不是一个问题,因为我是这个项目的唯一开发人员,但这是一个我不满意的代码气味。是否有一些我可以使用的路径变量,比如它仍然指向实际的设计时数据(不是任何临时的、已部署的文件),但是相对于活动的、开放的项目来说呢?
https://stackoverflow.com/questions/34625065
复制相似问题