Code first Seed 方法中的错误 - 无法更新时间戳列

Error in Code first Seed method - Cannot update a timestamp column

我正在尝试将种子方法 运行 设置为 table(配置值)中的 create/update 值。初始 运行 成功并创建了 "TestSeed" 记录。但是更新会抛出以下错误。

这是我的种子方法,

 context.SystemValues.AddOrUpdate(
            sv => sv.Name,
            new SystemValue { Name = "TESTSEED", Description = "Seed test1.",    CreatedBy = "Sys", CreatedOn = DateTime.UtcNow, Value = "TESTSEED", ModifiedBy = "Sys", ModifiedOn = DateTime.UtcNow }
            );
        context.SaveChanges();

并且 AutomaticMigrationsEnabled = false

系统值class,

public partial class SystemValue
{
    public int SystemValueId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
    public string Description { get; set; }
    public System.DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
    public System.DateTime ModifiedOn { get; set; }
    public string ModifiedBy { get; set; }
    public byte[] Version { get; set; }
}

更新数据库出错,

PM> Update-Database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. No pending explicit migrations. Running Seed method. System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot update a timestamp column. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)

为什么这个更新不起作用?我错过了什么吗?

编辑

我注意到的一件事是 RowVersion 字段不可空。我可以通过代码优先使它可以为空吗?

您需要告诉 EF 这是一个 timestamp / rowversion 列,这样它就不会尝试更新它。您可以通过在该列上添加 [Timestamp] 属性来执行此操作:

public partial class SystemValue
{
    public int SystemValueId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
    public string Description { get; set; }
    public System.DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
    public System.DateTime ModifiedOn { get; set; }
    public string ModifiedBy { get; set; }
    [Timestamp]
    public byte[] Version { get; set; }
}

SQL服务器中的TIMESTAMP / ROWVERSION列是一个特殊的列,只有SQL服务器内部可以更新——你作为数据库程序员只能阅读它出去。它跟踪行的版本,例如当你读取一行时,你可以记下它的版本,当你再次写入它时,你可以检查该行在你读取它之后是否已经被修改(那么该行版本列将有一个不同的比你读到的更有价值)

Marc_S 是正确的。但是在应用此更改时需要考虑一件小事。如果您将 "TimeStamp" 属性添加到现有版本字段,并且当我 运行 更新数据库时,它会给出另一个错误 - "Cannot update" 版本数据类型我必须先删除现有版本。因此,您需要先将其删除。

第 1 步 - 删除现有版本字段,添加新迁移并执行更新数据库。

第 2 步 - 使用 "TimeStamp" 添加版本字段并执行迁移和更新数据库。

如果您将 EF 数据库优先转换为 EF 代码优先,则可能会发生我提到的问题。当我最初这样做时,我错过了在迁移过程中测试这个系统值 class。