2012-07-28 86 views
1

以下代码中的Save方法失败,并显示错误“找不到或未找到行”。LINQ to SQL - 使用OnPropertyChanged更新时出现“未找到或已更改行”

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

question.Text = "some text"; 

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

问题是使用CodeSmith和PLINQO模板生成的DTO。但是,仅在执行OnPropertyChanged事件的自定义覆盖后才会出现“未找到或更改行”错误,以便在创建或修改记录时自动插入。我分析了生成的查询,当执行getQuestionById方法时,它执行正常的select语句。但是,如果修改日期返回为'2012-07-28 12:15:00.900',当我尝试保存记录时,更新失败,因为它正在添加Modified ='2012-07-28 12:15: 00.903'更新为更新语句,这与数据库中存在的数据不同。所以我知道这事做与添加到产生问题的对象下面的代码:

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永远不会使用除秒更高的精度域。我可以使用这个作为最后的手段,但我已经将相同的代码添加到其他具有相同数据类型的表中一段时间​​没有任何问题,并且想知道为什么它只发生在这个表中。这似乎也是随机失败的,我没有具体的步骤来重现它,但是当我没有调试时,它似乎更频繁地发生。

回答

0

我的猜测是你在数据库中使用你的Modified(和/或Created)列来检查并发性。您也自己更新此专栏。这种混合是不正确的。

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

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

+0

嗨马丁,谢谢你的回应。我们正在使用乐观并发性,所以我认为应该检查表中的所有列以确保没有任何变化。我正在尝试做的事(这对其他表起作用)是更新有关谁在对象上更新其他字段时被修改的人的信息(所以当我将.Text设置为“某些文本”时,也应该在OnPropertyChanged上触发,并在同一个对象上设置.Modified和.Modified)。出于某种原因,它正在更新语句中使用更新后的修改日期而不是缓存值。 – Carl 2012-07-30 14:40:27

+0

您可以检查L2S设计器中修改的列的问题(对于表无法正常工作)和另一个带有确实功能的表,可以检查自动生成值,自动同步和更新检查的属性值?有什么区别? – Maarten 2012-07-31 05:55:39