通过linq to sql更新行时无声失败

本文关键字:无声 失败 更新 linq to sql 通过 | 更新日期: 2023-09-27 17:53:27

我有一些c#代码,看起来像下面的例子:

foreach (car c in listOfCars) {
  c.garage.last_opened_at = DateTime.Now;
}
db.SubmitChanges();

基本上,carsgarages是一对一的关系(我知道这是一个有点缺陷的例子),我正在更新每个车库上次打开的时间。

当我检查数据库时,虽然,last_opened_at字段没有更新(没有显示错误消息)。有什么建议吗?我查看了SO和Google,我看到的解决方案都提到garage需要有一个主键。但是我仔细检查了一下,我的garage表确实使用了与它相关联的汽车的外键作为主键。

是否存在主键兼任外键的问题(即,我是否需要一个专用的主键列)?

通过linq to sql更新行时无声失败

这里有几种可能性:last_opened_at被指定为数据库提供的字段,您没有在linq to sql类中列出主键,并且更不可能的是,您的listOfCars不是来自相同的数据库上下文。

如果您将字段标记为由数据库生成,这是使用时间戳或数据库默认值字段时的典型场景,那么linq to sql将永远不会尝试写入该属性。

如果linq to sql类上没有主键,无论数据库正在做什么,它都不会写入表。只要主键是主键,主键同时也是外键就不会有问题。我曾经遇到过这种情况,并认为我记得在这种情况下有一个错误,但我不是100%确定。

如果您从一个数据上下文中生成listOfCars,并试图将它们保存在另一个数据上下文中,则第二个数据上下文中甚至不知道这些实体的存在。您可以通过确保使用相同的数据上下文或将实体附加到新上下文来解决这个问题。

如果在循环中移动对SubmitChanges的调用怎么办?

foreach (car c in listOfCars) {
  c.garage.last_opened_at = DateTime.Now;
  db.SubmitChanges();
}

您错过了一个实际更新模型的电话。我认为你的例子应该是这样的:

foreach(car c in listOfCars) {
    c.garage.last_opened_at = DateTime.Now;
}
db.AcceptAllChanges();
db.SubmitChanges();

同样,更新永远不会静默失败。如果更新失败,它将抛出UpdateException。在您的情况下发生的是,您的代码要更新,但没有看到模型中接受的更新,因此没有更新任何内容。如果主键或外键约束有问题,就会出现异常。