如何在一个只有一个查询到db的计数器字段上执行+1?

时间:2015-12-01 00:26:02

标签: c# sql sql-server asp.net-mvc entity-framework

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

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();
    }
}

但是这样我必须对db进行2次查询。一个用于获取当前总计数,另一个用于更新值。

有没有办法只使用实体框架对db进行一次查询?

我想尝试这样的事情:

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 个答案:

答案 0 :(得分:-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值选择为变量,按照@adjustment中的值指定调整它,(添加三个订阅?传递三个。删除三个订阅?传递一个负三个)然后将值更新为保存的行。最后,返回仅包含调整后的subscriptionCount值的行。

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

我留给你实现实体框架代码来处理存储过程。我不相信你可以在实体框架内使用一个电话对价值做同样的直接操纵,但我非常愿意以其他方式展示。

快乐编码。