首先,不幸的是,我无法更改数据库并寻找“费时的”解决方案。我意识到我要的不是最佳实践,而是足够的免责声明...
在适当的情况下,CRUD进程都包含@ts的输入/输出参数,以避免并发问题。
我正在使用DevExpress WebForms GridView-完美运行,而不是问题。
GridView正在使用MS SqlDataSource。它的选择命令正在调用MyTable_List proc。它的插入命令将调用MyTable_Insert proc。两者都能完美地工作。
不是更新。上网浏览并尝试找出是否有可能。所以更新基本上是这样:
SQL:
CREATE PROC MyTable_Update
@key int
@name varchar(100)
@ts timestamp output
AS
IF (SELECT TOP 1 1 FROM MyTable WHERE key = @key and ts = @ts) IS NULL
BEGIN
RAISEERROR('someone else changed this, reload, try again, 00, 00);
RETURN;
END
--[simple update the table logic]
SELECT @ts = ts FROM MyTable WHERE key = @key
数据源:
<asp:SqlDataSource id="ds" runat="server" ... OnUpdating="ds_Updating" UpdateCommand="MyTable_UPDATE" UpdateCommandType="StoredProcedure">
<UpdateParameters>
<asp:Parameter Name="key" Type="Int32" />
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Direction="InputOutput" Name="ts" Type="String" DefaultValue="0" /> <!-- i know, bear with me -->
</UpdateParameters>
</asp:SqlDataSource>
C#:
protected void myGrid_StartRowEditing(object sender, [DevEx].ASPxStartRowEditingEventArgs e)
{
//get the timestamp value from the db for this row being edited
int key = (Int32)myGrid.GetRowValuesByKeyValue(e.EditingKeyValue, "key");
var ts = db.MyTable_Get(key).First().ts; //actually getting the ts from the database
Session["MyTable_ts"] = ts;
}
protected void ds_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
//override what was set in the aspx
var p = e.Command.Parameters["@ts"];
p.DbType = Binary;
p.Direction = ParameterDirection.InputOutput;
p.Size = 8;
var ts = (System.Data.Linq.Binary)Session["MyTable_ts"];
p.Value = ts;
}
最后,当我开始在网格中的一行上进行编辑时,将启动StartRowEditing,并按预期方式将db中的时间戳值保存到会话var中(显然,.NET中的格式与SQL不同)。当我尝试提交更改(在DevEx网格编辑器上单击“更新”)时,ts_Updating触发,所有代码无一例外地完成。然后,当SqlDataSource触发实际更新时,它抛出“无法从中转换参数值”到DevEx网格的“二进制到字节[]”。并通过网格的UI进行报告。
我如何(甚至有可能?)将db时间戳值改组为会话,然后通过SqlDataSource更新参数发送它?
同样,我意识到我可以通过写出所有CSLA甚至只使用ObjectDataSource并写出所有更新逻辑来克服这个问题,但是我花了一些时间来完成一些网格并移动和移动继续-在项目中炸更大的鱼。
谢谢!
答案 0 :(得分:1)
想通了-很愚蠢,我却忽略了它。 System.Data.Linq.Binary的ToArray()将转换为Byte []。在函数的最后一行上向ts添加.ToArray()将转换为SqlDataSource可以传递回数据库的适当类型,从而允许Timestamp值匹配,从而通知db没有并发问题。>
protected void ds_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
//override what was set in the aspx
var p = e.Command.Parameters["@ts"];
p.DbType = Binary;
p.Direction = ParameterDirection.InputOutput;
p.Size = 8;
var ts = (System.Data.Linq.Binary)Session["MyTable_ts"];
p.Value = ts.ToArray(); //Binary must be cast to an Array (of Byte)
}