LINQ to SQL从不同的数据上下文中断开了更新对象

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

我正在使用ASP.NET和C#,并尝试使用linq to sql来更新上面链接的博客上展示的数据上下文。 我正如上所述在表中创建了timestamp字段,并使用以下方法:

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

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

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

我所说的每本书和资源都说这是实现它的方法,但是没有一本关于这个TimeStamp属性的详细信息。

我知道这很快捷,所以如果有人知道,请告诉我。

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

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

有两种常见的情况:

1:如果你只是执行一个短暂的操作,首先从数据库中取出记录 – 对对象进行更改,然后只是SumbitChanges()[所有具有相同的数据上下文]。 数据上下文将为您处理并发。

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

既然您说您在表中创建了时间戳字段,我想知道,如果稍后添加此列,则可能无法正确设置列属性。 您可能想要在DBML设计器中检查TimeStamp列上的属性。 确保:

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

服务器数据类型应为rowversion NOT NULL

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

此外,现在您有一个时间戳列,对于所有其他列, UpdateCheck应设置为Never