LINQ to SQL断开了更新对象与不同数据上下文的连接
本文关键字:数据 上下文 连接 对象 SQL to 断开 更新 LINQ | 更新日期: 2023-09-27 17:48:50
链接
我将ASP.NET与C#结合使用,并尝试使用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属性。
我知道这很快也很容易,所以如果有人知道,请告诉我。
既然您说您在表中创建了时间戳字段,我想知道在稍后添加此列的情况下,列属性是否设置不正确。您可能需要在DBML设计器中检查TimeStamp列的属性。确保:
AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never
服务器数据类型应为rowversion NOT NULL
如果未将其设置为始终自动生成和同步,则不会从插入中返回行版本,因为插入完成时您尚未对其进行更改。即使这个值是由数据库生成的,DataContext也需要知道这一点,以便能够正确处理它。
此外,现在您有了时间戳列,对于所有其他列,UpdateCheck
应该设置为Never
。
如果您有一个时间戳列,那么要更新记录(来自普通对象):是的,我希望必须分配它。否则,您将失去使用时间戳进行乐观并发检查的能力。
这个想法是,当你拿到(断开连接的)对象时,你会复制一份时间戳,然后当你更新时,你可以使用这个列来验证是否没有其他人编辑过该行。
有两种常见场景:
1:如果您只执行一个短期操作,请先从数据库中取出记录-对对象进行更改,然后简单地SumbitChanges()[所有操作都具有相同的数据上下文]。数据上下文将为您处理并发性。
2:如果您正在断开对象的连接(例如,将其传递给客户端应用程序一段时间),则使用类似序列化的东西(LINQ到SQL对象支持DataContractSerializer(可选;您需要启用它))。因此,在服务器上序列化对象,将其传递给客户端——客户端对其副本进行更改并将其传递回。服务器对其进行反序列化,并使用Attach()和SubmitChanges()。内存中的记录应该仍然具有从数据库中提取时的时间戳,因此我们可以在记录断开连接的所有时间执行乐观并发。