2016-03-02 190 views
2

我想运行种子方法来创建/更新表(配置值)中的值。初始运行成功并创建了“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 =假

系统值类,

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 >更新 - 数据库 指定'-Verbose'标志来查看应用于目标数据库的SQL语句。 没有待处理的显式迁移。 运行种子法。 System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。详情请参阅内部例外。 ---> System.Data.Entity.Core.UpdateException:更新条目时发生错误。详情请参阅内部例外。 ---> System.Data.SqlClient.SqlException:无法更新时间戳列。 在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔breakConnection,动作1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction) 在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔callerHasConnectionLock,布尔asyncClose) 在System.Data。 SqlClient.TdsParser.TryRun(runBehavior runBehavior,SqlCommand的cmdHandler,SqlDataReader的数据流,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,布尔& dataReady)

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

编辑

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

回答

1

您需要告诉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 Server中的TIMESTAMP/ROWVERSION列是一个特殊的列,只有SQL Server内部可以更新 - 你作为一个数据库程序员只能读取出来。它跟踪行的版本,例如当你读一行时,你可以记录它的版本,当你再次写它时,你可以检查行是否已经被修改,因为你读过它(然后该行版本列会有不同价值比你读的)

0

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

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

第2步 - 添加带有“TimeStamp”的版本字段并执行迁移和更新数据库。

如果您将EF数据库优先转换为EF代码优先,则可能会出现我提到的问题。当我最初做这件事时,我错过了在迁移过程中测试这个System Values类。