UPDATE后使用旧值进行CASE SELECT使用旧值

时间:2018-08-07 11:50:07

标签: sql .net sql-server entity-framework tsql

我遇到了由实体框架生成的sql语句组合的问题。

在更新语句完成并执行选择后,似乎没有立即设置powerloss字段的更新值。

我不知道那是否有可能。 也许我只是想念一些东西。

代码执行后,更新和选定的行以及表中的数据正确。

应该做什么(99%的时间都可以做到)

我从设备获取了一个counterValue并将其插入到sql-server 2008 R2(SP3)上的表中。如果设备断电并且在某个时候恢复供电,则数据库中最后一个counterValue条目中的“ powerloss”字段将更新为1(true)。默认情况下,该字段为0(false)。

此后,我查询该设备的最后一个counterValue并将其取反。 但仅当字段“ powerloss”为0(false)时。否则查询必须返回零。

出了什么问题

有时候(非常罕见),在选择之前,当powerloss字段更新为1(true)时,我得到了取反的counterValue。

至少这是我的日志文件显示给我的内容(记录了每个查询)。

代码的作用

  1. 创建dbContext
  2. BeginTransaction(isolationLevel.ReadComitted)
  3. WriteNewCounterValue(在Powerloss之后)

    1. 更新字段powerloss=true

    2. 选择计数器值取决于Powerloss字段中的值

      offset = (From qItem In DB.SlaveCounterEntries 
                Where qItem.deviceId= deviceId
                And qItem.Received < timestamp 
                Order By qItem.Received Descending 
                Select If(qItem.Powerloss = True, 0, -qItem.CounterValue) 
                Take 1).SingleOrDefault()
      
    3. 在表中插入新的计数器值

  4. 提交交易
  5. 处置dbContext

发芽的sql语句

更新语句:

UPDATE [dbo].[slaveCounter]
    SET [powerloss] = @0
    WHERE ([id] = @1)
    -- @0: 'True' (Type = Boolean)
    -- @1: '3371747' (Type = Int32)
    -- Executing at 29.06.2018 05:57:24 +02:00
    -- Completed in 0 ms with result: 1

select语句(更新后14毫秒):

SELECT TOP (1) 
    [Project1].[C1] AS [C1]
    FROM ( SELECT 
        CASE WHEN (1 = [Extent1].[powerloss]) THEN 0 ELSE  -([Extent1].[counterValue]) END AS [C1], 
        [Extent1].[datReceived] AS [datReceived]
        FROM [dbo].[slaveCounter] AS [Extent1]
        WHERE ([Extent1].[slaveId] = @p__linq__0) AND ([Extent1].[datReceived] < @p__linq__1)
    )  AS [Project1]
    ORDER BY [Project1].[datReceived] DESC

    -- p__linq__0: '48' (Type = Int16, IsNullable = false)
    -- p__linq__1: '28.06.2018 23:00:03' (Type = DateTime2, IsNullable = false)
    -- Executing at 29.06.2018 05:57:24 +02:00
    -- Completed in 0 ms with result: SqlDataReader

1 个答案:

答案 0 :(得分:1)

我找到了似乎更新语句不起作用的原因:

另一个事务添加了第二条记录,该记录具有相同的counterValue且未更新,后来被删除。 因此,仅保留“正确”条目。

回想起来,一切似乎都很清晰^^