1

以下代码中的 Save 方法失败,并出现错误“未找到或更改行”。

Question question = questionService.getQuestionById(id); 
// returning Context.Question.Where(q => q.id == id).SingleOrDefault()

question.Text = "some text";

questionService.Save(question); 
// Context.SubmitChanges();

Question 是使用 CodeSmith 和 PLINQO 模板生成的 DTO。但是,“未找到或更改行”错误仅在对 OnPropertyChanged 事件实施自定义覆盖以在创建或修改记录时自动插入之后发生。我分析了生成的查询,当执行 getQuestionById 方法时,它正在执行一个正常的选择语句。但是,如果修改日期返回为“2012-07-28 12:15:00.900”,当我尝试保存记录时,更新失败,因为它正在添加 Modified = '2012-07-28 12:15: 00.903' 到更新语句,这与数据库中存在的内容相差几毫秒。所以我知道这与添加到生成的 Question 对象的以下代码有关:

protected override void OnPropertyChanged(string property)
{
    this.UpdateProperties(property);
    base.OnPropertyChanged(property);
}

public static void UpdateProperties(this object updatedObject, string property)
{
    if (property == created || property = modified) return;
    // prevents an infinite loop 

    Update(updateObject);
    // sets updatedObject.Created and updateObject.Modified fields
}

我发现一些帖子建议在 dbml 中将 UpdateMode 设置为从不用于使用比秒更高的精度的字段。我可以将此作为最后的手段,但我一直在将相同的代码添加到具有相同数据类型的其他表中一段时间​​没有任何问题,并且想了解为什么它只发生在这个表中。这似乎也有点随机失败,我没有重现它的具体步骤,但是当我不调试时它似乎确实发生得更频繁。

4

1 回答 1

0

我的猜测是您正在使用数据库中的已修改(和/或已创建)列来检查并发性。您也在自己更新此列。这种混合是不正确的。

更好的方法是使用时间戳作为并发检查列。此列将由 SQL 服务器设置(假设这是您使用的),并且不是日期时间,而是一些内部唯一数据库生成的值。

一些谷歌搜索给了我这篇文章,我认为它将很好地解释如何设置时间戳列的基础知识。

于 2012-07-30T06:00:21.773 回答