我在当前项目中一直使用EF迁移一段时间,并且所有工作都很棒,直到今天,情况如下:EF 6 CodeFirst添加迁移脚手架并生成不存在的更改
- 我做了添加一个字符串属性
- 我打电话的API函数的小变化,并得到了有变化模型
- 我跑的命令是错误的“添加迁移MigrationXYZ”
- 一新的迁移是在没有发生额外变化的情况下创建的
我跑了“添加迁移MigrationXYZ - 强制”,以确保它不是一个有一点问题,我放弃了DB,重启VS(2015),但都是一样的
的另一个问题是,即使如果我使用脚手架完成的迁移,错误仍会返回说“无法更新数据库以匹配当前模型,因为有待处理的更改...”
查看这些更改后,它们都只是一个关于具有[Required]属性的字符串属性和脚手架需要使其可以为空,下面是一个示例。
public partial class MigrationXYZ: DbMigration
{
public override void Up()
{
AddColumn("dbo.Foos", "NewProperty", c => c.String());//<-- Expected Change
AlterColumn("dbo.Bars", "Name", c => c.String());//<-- Unexpected Change
}
public override void Down()
{
AlterColumn("dbo.Bars", "Name", c => c.String(nullable: false));//<-- Unexpected Change
DropColumn("dbo.Foos", "NewProperty");//<-- Expected Change
}
}
public class Bar
{
//This was not touched in ages, some even before adding the first migration
[Required]
public string Name { get; set; }
}
现在我坚持,不知道如何在移动状态解决这个问题...腐败
编辑
我一直在试图调试Add-Migration
命令理解EF为什么看到模型与实际不同,但是当您拥有需要签名DLL的Identity等依赖项时,使用EF源是不可能的。
但是更多的研究使我这导致this blog post通过@trailmax和破译迁移哈希代码answer here,并与在EF源一点点搜索我做了一个小的应用程序来提取这两种当前模型和最后一个迁移模型进行比较。
代码即可获得当前的模型表示的XML
//Extracted from EF Source Code
public static class DbContextExtensions
{
public static XDocument GetModel(this DbContext context)
{
return GetModel(w => EdmxWriter.WriteEdmx(context, w));
}
public static XDocument GetModel(Action<XmlWriter> writeXml)
{
using (var memoryStream = new MemoryStream())
{
using (var xmlWriter = XmlWriter.Create(
memoryStream, new XmlWriterSettings
{
Indent = true
}))
{
writeXml(xmlWriter);
}
memoryStream.Position = 0;
return XDocument.Load(memoryStream);
}
}
}
//In Program.cs
using (var db = new DbContext())
{
var model = db.GetModel();
using (var streamWriter = new StreamWriter(@"D:\Current.xml"))
{
streamWriter.Write(model);
}
}
的代码来提取迁移模型在XML
//Code from Trailmax Tech Blog
public class MigrationDecompressor
{
public string ConnectionString { get; set; }
public String DecompressMigrationFromSource(IMigrationMetadata migration)
{
var target = migration.Target;
var xmlDoc = Decompress(Convert.FromBase64String(target));
return xmlDoc.ToString();
}
public String DecompressDatabaseMigration(String migrationName)
{
var sqlToExecute = String.Format("select model from __MigrationHistory where migrationId like '%{0}'", migrationName);
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
var command = new SqlCommand(sqlToExecute, connection);
var reader = command.ExecuteReader();
if (!reader.HasRows)
{
throw new Exception("Now Rows to display. Probably migration name is incorrect");
}
while (reader.Read())
{
var model = (byte[])reader["model"];
var decompressed = Decompress(model);
return decompressed.ToString();
}
}
throw new Exception("Something went wrong. You should not get here");
}
/// <summary>
/// Stealing decomposer from EF itself:
/// http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Migrations/Edm/ModelCompressor.cs
/// </summary>
private XDocument Decompress(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
return XDocument.Load(gzipStream);
}
}
}
}
//Inside Program.cs
var decompresser = new MigrationDecompressor
{
ConnectionString = "<connection string>"
};
var databaseSchemaRecord = decompresser.DecompressDatabaseMigration("<migration name>");
using (var streamWriter = new StreamWriter(@"D:\LastMigration.xml"))
{
streamWriter.Write(databaseSchemaRecord);
}
不幸的是我仍然无法找到问题,模型和最后一次迁移之间的唯一区别是增加的属性的预期变化,没有出现意想不到的变化,在运行EF建议的迁移之后,然后将当前模型与建议的迁移进行比较,仍然该模型与变更不匹配,但不应该为null的模型仍然不为空,而建议的迁移将其显示为可以为null 。
预期的变化显示
<Property Name="NewProperty" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
.
.
.
<ScalarProperty Name="NewProperty" ColumnName="NewProperty" />
.
.
.
<Property Name="NewProperty" Type="nvarchar(max)" Nullable="true" />
我不介意downvote,但是请解释downvote的原因,如果问题不清楚,或者问题的原因非常明显,那么请指出我的答案。 – MEYWD
其他迁移中的Bars.Name'是否有任何更改?我在一个案例中发现手动修改的迁移脚本产生了非常类似的错误。 – trailmax
也在使用什么版本的SQL Server(假设这是SQL Server)?我在开发机器上使用SQL Server 2008 R2时遇到了问题。但是,升级到2014年时,问题消失了 – trailmax