0

我正在使用 Entity Framework 使用 Code First 模型生成的数据库。我已经更改了几次模型,并且熟悉了包管理器控制台,它会根据模型的更改生成代码来修改数据库。

到目前为止它运行良好,直到我添加了几个字段来执行乐观并发控制。这些是我添加到模型中的字段:

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 已经令人沮丧,我认为只实现我自己的 rowversion 并发检查会更容易,而且它在 Session-State 模型上就像一个魅力。

我尝试简单地删除我的 .mdf 文件并添加另一个具有相同名称的文件,以便它可能会从头开始重新构建表,但是哦不,这显然不是那么简单地解决。我对仅将时间戳存储为字符串的想法持开放态度,因为 EF 在尝试在 C# DateType 值和 SQL Server 日期时间值之间来回切换时似乎消化不良,但我宁愿尝试将其保留为如果可能,日期时间。

无论如何,如果有人可以提供一些关于我如何克服这个问题的指示,我将非常感激!

4

2 回答 2

2

时间戳字段不可为空。当 SQL 添加列时,它没有默认值。我猜测 SQL 或 EF 试图只为现有记录上的新列提供一个空字符串,这会导致转换问题。

尝试制作时间戳DateTime?即可以为空。或者,我相信迁移为您提供了一种方法来提供用于现有列的默认值(不在我的电脑上,所以无法检查)。

于 2012-03-03T05:57:11.787 回答
0

@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));
    }
}
于 2012-08-14T20:07:30.063 回答