You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让调用存储过程的asp:SqlDataSource支持TIMESTAMP(ROWVERSION)并发校验

.NET Framework中SqlDataSource对接SQL Server TIMESTAMP并发校验解决方案

项目背景

  • 项目基于.NET Framework,覆盖WinForm、WebForms场景,对接MS SQL Server数据库
  • 核心业务表均包含tsModified TIMESTAMP(又称ROWVERSION)列,用于避免并发更新冲突
  • 项目规范要求所有CRUD操作及业务逻辑必须通过存储过程实现,应用层不允许直接操作数据表

核心诉求

希望直接使用拖拽asp:SqlDataSource控件的便捷开发方式,实现UPDATE操作时自动传递TIMESTAMP列参数完成并发校验,无需额外编写分部类使用asp:ObjectDataSource增加开发工作量。

项目现有存储过程基础结构

CREATE PROC Customer_List
  @pk_Customer INT = null
AS
SELECT id, name, tsModified 
FROM Customer 
WHERE @pk_Customer IS NULL OR @pk_Customer = id;

CREATE PROC Customer_Update
  @id INT,
  @name varchar,
  @tsMod TIMESTAMP
AS
IF NOT EXISTS (SELECT TOP 1 1 FROM Customer where id=@id and tsModified=@tsModified)
    -- 实际业务中此处抛出并发冲突错误,提示用户刷新后重试
    RAISERROR('数据已被其他用户修改,请刷新页面后重试', 16, 1)
    RETURN

UPDATE Customer SET name = @name WHERE id = @id;

具体解决方案

仅需要对asp:SqlDataSource做三处配置调整即可实现需求:

  1. 配置查询存储过程返回的tsModified列作为并发校验字段
    首先设置SqlDataSource的ConflictDetection属性为CompareAllValues,同时将tsModified加入DataKeyNames属性:
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
         ConflictDetection="CompareAllValues"
         DataKeyNames="id,tsModified"
         SelectCommand="Customer_List" 
         SelectCommandType="StoredProcedure"
         UpdateCommand="Customer_Update" 
         UpdateCommandType="StoredProcedure">
    
  2. 显式定义UPDATE存储过程的TIMESTAMP参数类型
    在UpdateParameters集合中手动指定@tsMod参数的类型为Object,方向为Input,并且绑定原始值:
    <UpdateParameters>
        <asp:Parameter Name="id" Type="Int32" />
        <asp:Parameter Name="name" Type="String" />
        <asp:Parameter Name="tsMod" Type="Object" Direction="Input" 
            SourceField="tsModified" OriginalValuesOnly="true" />
    </UpdateParameters>
    </asp:SqlDataSource>
    
  3. 确保绑定控件(如GridView、FormView)保留tsModified字段原始值
    如果使用GridView展示数据,需要在列定义中添加隐藏的tsModified绑定列:
    <asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="id,tsModified">
        <Columns>
            <asp:BoundField DataField="id" HeaderText="客户ID" ReadOnly="true" />
            <asp:BoundField DataField="name" HeaderText="客户名称" />
            <asp:BoundField DataField="tsModified" Visible="false" />
            <asp:CommandField ShowEditButton="true" />
        </Columns>
    </asp:GridView>
    

注意:不要将tsModified列的类型设置为Binary,SqlDataSource对二进制类型的原始值传递存在已知bug,设置为Object类型会自动保留TIMESTAMP的二进制原始值,可正常完成并发校验。

内容的提问来源于stack exchange,提问作者Ted Krapf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:48:04