4

http://geekswithblogs.net/michelotti/archive/2007/12/17/117791.aspx

我正在使用带有 C# 的 ASP.NET,并尝试使用 linq to sql 来更新数据上下文,如上面链接的博客中所示。我按照说明在表中创建了时间戳字段,并使用以下方法:

private void updateRecord(TableName updatedRecord)
{
 context db = new context();
 db.TableName.Attach(updatedRecord,true);
 db.SubmitChanges();
}

我的问题是,在尝试在数据上下文中调用 Attach 方法之前,您是否应该将 timeStamp 字段分配给 updatedRecord 中的任何内容?

当我运行此代码时,我得到以下异常:System.Data.Linq.ChangeConflictException: Row not found or changed. 在将对象传递给此更新方法之前,我更新了所有字段,包括我正在更新的记录的主键。在调试期间,对象的 TimeStamp 属性显示为 null。我不确定它是否应该这样。

我拥有的每一本书和资源都说这是这样做的方法,但没有一个详细介绍这个 TimeStamp 属性。

我知道这既快速又简单,所以如果有人知道,请告诉我。

4

2 回答 2

3

既然你说你在表中创建了时间戳字段,不知道是不是在后面添加了这个列的情况下,可能是列属性设置不正确。您可能需要检查 DBML 设计器中 TimeStamp 列上的属性。确保:

AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never

服务器数据类型应该是rowversion NOT NULL

如果未将其设置为始终自动生成和同步,则不会从插入返回行版本,因为插入完成时您没有更改它。即使这个值是由数据库生成的,DataContext 也需要知道这一点,以便它可以正确处理它。

此外,既然您有一个时间戳列,UpdateCheck应该Never为所有其他列设置为。

于 2008-11-07T21:44:03.897 回答
1

如果您有一个时间戳列,那么要更新一条记录(来自一个普通对象):是的,我希望必须分配它。否则,您将失去使用时间戳进行乐观并发检查的能力。

这个想法是当您获得(断开连接的)对象时获取时间戳的副本,然后当您更新时,您可以使用此列来验证没有其他人编辑过该行。

有两种常见的情况:

1:如果您只执行短暂的操作,请先从数据库中取出记录 - 对对象进行更改,然后简单地 SumbitChanges() [都具有相同的数据上下文]。数据上下文将为您处理并发。

2:如果要断开对象的连接(例如将其传递给客户端应用程序一段时间),则使用序列化之类的方法(LINQ-to-SQL 对象支持 DataContractSerializer(可选;您需要启用它))。因此,在服务器上序列化对象,将其传递给客户端 - 客户端对其副本进行更改并将其传回。服务器对其进行反序列化并使用 Attach() 和 SubmitChanges()。内存中的记录应该仍然具有从数据库中提取时的时间戳,因此我们可以在记录断开连接的所有时间执行乐观并发。

于 2008-11-07T20:44:06.937 回答