如何在只有一个数据库查询的情况下对计数器字段执行+1

本文关键字:情况下 计数器 字段 执行 查询 有一个 数据库 | 更新日期: 2023-09-27 18:25:11

我有一个字段,用于计算用户的订阅总数。现在我更新这个字段如下:

using (var context = new AppDbContext())
{
    var foundEntry = context.Users.Find(id);
    if (foundEntry != null)
    {
        foundEntry.TotalSubscriptions = foundEntry.TotalSubscriptions + 1;
        context.Entry(foundEntry).CurrentValues.SetValues(foundEntry);
        var result = context.SaveChanges();
    }
}

但通过这种方式,我必须对数据库进行2次查询。一个用于获取当前总计数,另一个用于更新值。

有没有一种方法可以做到这一点,只需对带有实体框架的数据库进行一次查询?

我想试试这样的东西:

var user = new User() { Id = userId, TotalSubscriptions = currentS + 1 };
db.Users.Attach(user);
db.Entry(user).Property(x => x.TotalSubscriptions).IsModified = true;

但我面临的问题是,我必须首先获得当前计数,但不知道如何在一个查询中执行。我认为,对于原始SQL语句/查询,1个查询是可能的。

我正在尝试归档以下内容:https://stackoverflow.com/a/2762856/1286942但是具有实体框架。

更新

我也试过这样的东西:

var user = new User() { Id = userId };
db.Users.Attach(user);
user.TotalSubscriptions = context.Entry(user)
.Property(u => u.TotalSubscriptions).OriginalValue + 1;
db.Entry(user).Property(x => x.TotalSubscriptions).IsModified = true;

但是问题是.OriginalValue.OriginalValue总是返回0。因此TotalSubscriptions字段总是更新为-1或1。

更新#2

现在我只认为这是一个选项:

var numberOfUpdatedRows = context.Database
.ExecuteSqlCommand("UPDATE dbo.Users 
SET TotalSubscriptions = TotalSubscriptions + 1 
WHERE id = " + id + "");

如何在只有一个数据库查询的情况下对计数器字段执行+1

这类代码的基本方法是为SQL代码使用存储过程,并将变量值传递给该过程。这是解决你问题的可能办法。

CREATE PROCEDURE AdjustSubscriptions 
    @userid int,
    @adjustment int
AS
BEGIN
    DECLARE @subs int
    SET NOCOUNT ON
    UPDATE UserInfo
    SET @subs = currentS + @adjustment, currentS = @subs
    WHERE userID = @userid
    SELECT @subs AS SubscriptionCount
END

这将把currentS值SELECT到一个变量中,根据@adjustment中的值进行调整,(添加三个订阅?传递一个三。删除三个订阅。传递一个负三)然后将值更新到保存的行。最后,返回一个仅包含调整后的subscriptionCount值的行。

可以重写存储过程以返回OUTPUT变量中的值(如果实现正确,您只需将值返回到变量中,而不必处理记录集),甚至可以在过程结束时使用语句return@subs将调整后的值作为返回值返回。我强烈建议您不要使用RETURN@subs方法,因为它在smallint之外的字符串或值的返回时中断。

我让您实现实体框架代码来处理存储过程。我不相信在实体框架内使用一个调用可以对值进行同样的直接操作,但我完全愿意看到其他情况。

快乐编码。