Linq行未找到或更改
Error Message: Row not found or changed. Stack Trace: at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
这似乎是随机发生的。 我通过电子邮件发送了这些错误,并且报告的URL似乎总是对我有用,并且应该也适用于其他所有人。
我可以通过以下方式解决此错误
- 转到我的
dbml
布局 - 选择表中的每个字段都会导致冲突
- 右键单击并将属性
Update Check
设置为Never
这似乎可以防止抛出这些类型的错误。
但是,每当我有机会进入dmbl
,添加新表等时,记住继续这样做是很费力的。有没有更好的方法来解决这个问题? 我每天可能会得到50-100这对我的访客来说很糟糕。
每次我看到这个错误,都意味着在我加载记录/对象/任何东西和我试图保存它之间数据库中发生了一些变化。 没有失败,这是因为我的工作单位太大了。
我不知道您的应用程序的确切性质,但我假设您正在创建数据上下文,加载记录或记录列表,对其执行某些操作,咀嚼一些时间和处理器周期,然后在结束尝试将修改后的数据保存回数据库。 甚至可能加载一个记录/对象的实例并将其存储在类变量中一段时间,然后在页面加载或线程的末尾或任何试图保存更改的任何内容。 问题是因为LINQ存储了它的副本,即它想要更新的副本。 如果基础数据在此期间发生变化,那就会发疯。
问问自己,如果您在对象的整个生命周期内对数据进行锁定事务,该怎么办? 说你加载的任何东西都可以修改,在此期间没有其他人可以接触它。 基本上这就是这里的假设。 当然,LINQ对此更加乐观,如果您可能永远不会更新数据,那么锁定行或表是没有意义的,但您会考虑这些问题。 问问自己,如果要对对象进行严格的事务锁定,会有什么破坏或显着减慢,这可能会指向违规代码。
我的解决方案是尽可能减少我的工作单元。 不要加载对象并将其用作工作副本并将其存储回数据库,所有这些都在一个上下文中。 相反,加载对象并在一个步骤中提取所需的信息,然后找出需要应用的更改,然后加载/更新/保存对象。 当然它会导致更多的数据库往返,但可以更好地保证您正在使用最新的数据副本。 它仍将是“最后赢,赢”,这意味着如果有人在您处理数据时进行更新,则可能会丢失,但除非您使用事务锁定记录,否则这总是存在风险。 但是,如果其他人正在修改同一行中不相关的字段,那么它确实会为您带来灵活性,您可以同时对这些数据进行操作。
我有同样的问题,并通过比较dbml和db结构来解决它。 一个属性未设置为可空,这导致了问题。
因此,请检查您的dbml和可空属性。
GetTable()。Attach(newEntity,originalEntity);
如果您没有使用版本字段进行更新,则上述方法会参数化新的详细信息和旧的详细信息实体,如果此时更改了原始实体,您仍会得到相同的错误,这取决于您确定。 这就像一个魅力,我试过它。
如果数据库触发器更改正在更新的行中的任何列,即使您没有更新该特定列,也会发生这种情况。
您必须仔细检查您工作单元中受影响的任何表都没有触发器。 如果您使用的是更新触发器,那么您可能希望确保更新的列是NeverCheck 。
有时它非常简单……确保桌子上没有锁。 就我而言,在我调试时,SQL Server Management Studio UI保存了我不知道(不记得)的锁。 卸载它清除了那些锁,事情又重新开始了。
使用SQL事件探查器我跟踪了我的服务器的SQL事务,并意识到在SubmitChanges()
上传输的UPDATE
语句在WHERE
子句中包含错误的值 。 这是因为我有一个看起来像这样的属性:
class Position{ ... [Column] public int Pieces{ get{ this.pieces = this.Transformers.Count; return this.pieces; } set{ this.pieces = value; } } ... }
由于Transformers
是一个List
元素,它表示与另一个Transformers
表的一对多关系的列表,我手动必须用包含我的Position
对象的外键的每个Transformer
填充List。 如果由于某种原因,我不这样做,那么我将得到提到的错误,因为Pieces
属性偏离原始值。
因此, SubmitChanges()
上的SQL语句将搜索条目WHERE Pieces = somevalue
但条目中WHERE Pieces = somevalue
的实际值是anothervalue
。 所以基本上LINQ会认为,你在db中同时改变了一些东西,因为db不会给这个请求返回任何值。
如上所述,一种解决方案是:
[Column(UpdateCheck=UpdateCheck.Never)] public int Pieces { get { this.pieces= this.Transformers.Count; return this.pieces; } set { this.pieces= value; } }
当然,通过设置简单的getter函数也可以轻松解决这个问题
getPieces(){ return this.Transformers.Count(); }
和一个“无偏见”的财产
class Position{ ... [Column] public int Pieces{ get{ return this.pieces; } set{ this.pieces = value; } } ... }
我希望这可以对某人有所帮助。 我发布这个也是因为如果以前有其他人,它会为我节省数小时的生命。
我在Windows Phone 8上遇到了这个错误。我花了一段时间来弄清楚问题是什么。 基本上是这样的:
我有一个名为TrackingInformation的课程。 1.从服务器我获取了它的更新版本。 2.我的TileService使用它的信息更新了辅助磁贴,并且(!!)更新了1个属性并将其保存到手机上的本地数据库中。 3.我试图再次保存对象的第一个实例,在这里我收到错误“未找到或未更改行”。
对我来说,我只需要删除第三部分,它工作正常(我已经保存了更新版本)。 但由于一处房产发生了变化,因此抛出exception……
我不能等到EF7进入Windows Phone,对WP8上的当前EF非常头疼。
在我的案例中更新linq到sql架构的设计器解决问题