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个这对我的访客来说很糟糕。
答案 0 :(得分:50)
我有同样的问题,并通过比较dbml和db结构来解决它。一个属性未设置为可空,这导致了问题。
请检查您的dbml和可空属性。
答案 1 :(得分:28)
每次我看到这个错误,都意味着在我加载记录/对象/什么以及我试图保存它的时间之间数据库中发生了什么变化。没错,那是因为我的工作单位太大了。
我不知道您的应用程序的确切性质,但我假设您正在创建数据上下文,加载记录或记录列表,对其执行某些操作,咀嚼一些时间和处理器周期,以及然后在最后尝试将修改后的数据保存回数据库。甚至可能加载一个记录/对象的实例并将其存储在类变量中一段时间,然后在页面加载或线程的末尾或任何试图保存更改的内容。问题是因为LINQ存储了它的副本,即它想要更新的副本。如果基础数据在此期间发生变化,那就太疯狂了。
问问自己,如果在对象的整个生命周期内对数据进行锁定事务,该怎么办?说你加载的任何东西都可以修改,在此期间没有其他人可以接触它。基本上这就是这里的假设。当然,LINQ对它更加乐观,如果你可能永远不会更新数据,那么锁定行或表是没有意义的,但你会想到这些问题。问问自己,如果要对对象进行严格的事务锁定会导致什么会破坏或显着减慢,这可能会指向违规代码。
我的解决方案是尽可能减少我的工作单元。不要加载对象并将其用作工作副本并将其存储回数据库,所有这些都在一个上下文中。相反,加载对象并在一个步骤中提取所需的信息,然后找出需要应用的更改,然后加载/更新/保存对象。当然它会导致更多往返数据库,但可以更好地保证您正在使用最新的数据副本。它仍将是“最后赢,赢”,这意味着如果有人在您处理数据时进行了更新,则可能会丢失,但除非您使用事务锁定记录,否则这总是存在风险。但是,如果其他人正在修改同一行中不相关的字段,那么它确实会为您带来灵活性,您可以同时对这些数据进行操作。
答案 2 :(得分:2)
GetTable()。附加(newEntity,originalEntity);
如果您没有使用版本字段进行更新,上面的方法会参数化新的详细信息和旧的详细信息实体,如果此时更改了原始实体,您仍会得到相同的错误,这取决于您确保。这就像一个魅力,我尝试过。
答案 3 :(得分:2)
如果数据库触发器更改了您正在更新的行中的任何列,也会发生这种情况 - 即使您没有更新该特定列。
您必须仔细检查您工作单元中受影响的任何表都没有触发器。如果您使用的是更新触发器,那么您可能希望确保更新的列是 NeverCheck 。
答案 4 :(得分:1)
有时它非常简单......确保桌子上没有锁。就我而言,在我调试时,SQL Server Management Studio UI保存了我不知道(不记得)的锁。卸载它清除了那些锁,事情又重新开始了。
答案 5 :(得分:1)
使用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>
元素,表示与另一个Transformers
表的一对多关系列表,因此我需要手动填写每个Transformer
的列表包含我的Position
对象的外键。如果由于某种原因,我不这样做,那么我将得到提到的错误,因为Pieces
属性偏离原始值。
因此,SubmitChanges()
上的SQL语句将搜索条目WHERE Pieces = somevalue
,但条目中Pieces
的实际值为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; }
}
...
}
我希望这可以对某人有所帮助。我也发布了这个帖子,因为如果以前有其他人的话,它会为我节省数小时的生命。
答案 6 :(得分:0)
我在Windows Phone 8上遇到了这个错误。我花了一段时间来弄清楚问题是什么。基本上是这样的:
我有一个叫做TrackingInformation的课程。 1.从服务器我获取了它的更新版本。 2.我的TileService使用它的信息和(!!)更新了1个属性更新了辅助磁贴,并将其保存到手机上的本地数据库中。 3.我试图再次保存对象的第一个实例,在这里我得到错误&#34;未找到或更改行#34;。
对我来说,我只需要删除第三部分,它工作正常(我已经保存了更新版本)。但由于一处房产发生了变化,它引发了例外......
我不能等到EF7进入Windows Phone,对WP8上的当前EF感到非常头疼。
答案 7 :(得分:0)
在我的案例中将linq更新为sql架构的设计器解决问题
答案 8 :(得分:0)
我遇到了同样的问题。问题发生在更新行的地方。
例如,我有一个带有列的表:
id,firstname,lastname,age
我想使用dbml更新年龄。在探查器中,我看到了
更新age=@newage
,其中id=@id
和firstname=@firstname
和lastame=@lastname
。
但是在读取行和更新之间,其他一些过程更改了名字或姓氏值。 UPDATE失败是因为WHERE
子句对于其中一列具有不同的值,并且更新将@@rowcount==0
返回到dbml,这将使您得到的错误得到解决。