我使用的是Entity Framework使用Code First模型生成的数据库。此后,我对模型进行了几次更改,并熟悉了Package Manager控制台,它会根据对模型的更改生成代码来修改数据库。
到目前为止,它工作得很好,直到我添加了几个字段来执行乐观并发控制。以下是我添加到模型中的字段:
public int Rowversion { get; set; }
public DateTime MLTimestamp { get; set; }第二个字段名为"MLTimestamp“,但最初命名为Timestamp。我更改了它,试图修复我在尝试更新数据库时收到的错误。
因此,以下是包管理器生成的代码:
public partial class MediaTypeRowversion : DbMigration
{
public override void Up()
{
AddColumn("MediaTypes", "Rowversion", c => c.Int(nullable: false));
AddColumn("MediaTypes", "MLTimestamp", c => c.DateTime(nullable: false));
}
public override void Down()
{
DropColumn("MediaTypes", "MLTimestamp");
DropColumn("MediaTypes", "Rowversion");
}
}当我从包管理器控制台运行Update-Database时,我得到了这个错误消息:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.我不确定它认为我想要做什么转换。这是一个以前在数据库中不存在的字段。没有什么可以“转换”的。如上所述,第二个字段最初被命名为Timestamp,所以我拍了拍我的额头说,啊,数据库中肯定已经有这个名字的字段了。因此,我在我的模型和迁移代码中对其进行了更改,但仍然收到此错误。
这两个字段都没有数据注释为Timestamp。考虑到使用EF是多么令人沮丧,我认为只实现我自己的行版本并发检查会更容易,它就像Session-State样机上的魔力一样工作。
我试着简单地删除我的.mdf文件,然后添加另一个同名的文件,这样它可能会从头开始重新构建表,但是哦,不,这显然不是很容易解决的。我对将时间戳存储为字符串的想法持开放态度,因为EF在尝试在C# DateTime值和SQL Server DateType值之间来回切换时似乎消化不良,但如果可能的话,我更愿意将其作为datetime。
无论如何,如果任何人能提供一些关于如何克服这个问题的建议,我将不胜感激!
发布于 2012-03-03 13:57:12
时间戳字段不可为空。当SQL添加列时,它没有默认值。我猜测SQL或EF试图为现有记录上的新列提供空字符串,这会导致转换问题。
尝试将时间戳设为DateTime?即可为空的。或者,我认为Migrations为您提供了一种为现有列提供默认值的方法(不在我的PC上,因此无法检查)。
发布于 2012-08-15 04:07:30
@Frans让你走上了正确的道路。但是,如果您希望在不更改数据模型的情况下实现此目标,则可以修改迁移以将DateTime列添加为可空的,然后将其更改为可空的。
这将导致一个不能为空的列没有默认值定义(这意味着您必须在每次执行插入操作时提供它- sql永远不会生成日期时间)。
public partial class AddDateColumToMyEntity : DbMigration
{
public override void Up()
{
// EF4.3 bug, gotta create date nullable, then change to non-nullable
AddColumn("MyEntity", "SomeDateField", c => c.DateTime(nullable: true));
AlterColumn("MyEntity", "SomeDateField", c => c.DateTime(nullable: false));
}
}https://stackoverflow.com/questions/9543557
复制相似问题