我正在寻找一个等同于:
的LINQ查询UPDATE Person p SET p.Age = p.Age + 1 WHERE p.Id = 123
我知道解决方案是选择行然后更新它:
var p = db.Set<Person>.Where(p => p.Id==123);
p.Age = p.Age + 1;
db.SaveChanges();
但这不是一种安全的方式,因为在提交更改之前,某人可能会增加Age
的值,而我们会用错误的值覆盖该值。
问题:是否有能够转换为更新查询的LINQ查询:
UPDATE Person p SET p.Age = p.Age + 1 WHERE p.Id = 123
答案 0 :(得分:2)
据我所知,你不能在默认的实体框架中使用LINQ,所以你有的选择是:
尝试使用EntityFramework.Extended库。它有Update
扩展方法,因此在您的情况下将是:
db.Set<Person>.Where(p => p.Id==123).Update(p => new Person {Age = p.Age + 1});
这个库的作用是解析表达式树并构造原始更新sql查询到你的数据库。对于简单的情况,它应该可以正常工作(当然,由它生成的sql并不像你自己编写的那样干净,但对于EF本身也是如此)。
答案 1 :(得分:1)
这不是Linq方法,但您可以通过以下方式发出查询:
var incrementStep = 1;
var personId = 123;
db.Database.ExecuteSqlCommand("UPDATE Person p SET p.Age = p.Age + @p0 WHERE p.Id = @p1",
incrementStep, personId);
处理场景的另一种方法是通过行版本列处理乐观并发,该列跟踪上次更改行的时间(有关更完整的示例和说明,请参阅this文章)。
答案 2 :(得分:1)
如果我没有记错,你需要悲观的逻辑来处理EF中的这种情况。 我知道的一种方法是使用包含锁定提示的SQL语句从上下文加载对象(并在事务中执行)。
但是为了处理这种情况,我通常会使用存储过程并绕过ORM。