基于数据库值更新实体框架

本文关键字:实体 框架 更新 数据库 | 更新日期: 2023-09-27 18:08:29

在实体框架之前,如果我有一个产品的库存数量或订单数量,我会使用当前数据库值更新它的数量,如下所示:

UPDATE Products SET AvailableQty = AvailableQty - 2 WHERE ProductId = 1;

是否有一种方法来完成相同的事情与实体框架?框架似乎遵循加载,修改,更新模式:

Product product = db.Products.FirstOrDefault(x => x.ProductId == 1);
product.AvailableQty += 2;
db.SaveChanges();

但是,按照这种方法,有可能在初始加载数据和更新数据之间产品发生变化。我知道我可以在实体上有一个并发字段来阻止更新,但在大多数情况下,我不希望有用户干预(例如客户下订单或接收采购订单)。

是否有一个首选的方法来处理这些使用EF的情况,或者我应该只是回到原始SQL的这些场景?

基于数据库值更新实体框架

将查找和更新包含在事务中

using (var transaction = new System.Transactions.TransactionScope())
{
    Product product = db.Products.FirstOrDefault(x => x.ProductId == 1);
    product.AvailableQty += 2;
    db.SaveChanges();
    transaction.Complete();
}

"首选方法"是基于意见的,所以我只关注答案。EF允许您通过DbContext的database属性直接访问数据库。你可以使用ExecuteSqlCommand直接执行SQL。或者,您可以使用SqlQuery扩展方法。

ExecuteSqlCommand返回受影响的记录。并且,SqlQuery扩展方法允许您使用EF提供的填充。

同样,如果这还不够强大,您可以创建自己的命令,像这样:

var direct = mydbContext.Database;
using (var command = direct.Connection.CreateCommand())
{
    if (command.Connection.State != ConnectionState.Open) 
    { 
        command.Connection.Open(); 
    }
    command.CommandText = query.ToString(); // Some query built with StringBuilder.
    command.Parameters.Add(new SqlParameter("@id", someId));
    using (var reader = command.ExecuteReader())
    {
        if (reader.Read()) 
        {
            ... code here ...
            reader.Close();
        }
        command.Connection.Close();
    }
}