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

时间:2008-11-07 20:38:16

标签: c# linq-to-sql timestamp disconnected

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

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

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属性的详细信息。

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

2 个答案:

答案 0 :(得分:3)

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

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

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

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

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

答案 1 :(得分:1)

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

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

有两种常见情况:

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

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