Во-первых, к сожалению, я не могу изменить базу данных и ищу решение «не по времени». Я понимаю, что то, о чем я прошу, - это не лучшая практика, а достаточно оговорок ...
- MS SQL Server
- C # / .NET 4.xx
- WebForms
- dbo.MyTable - приложениям не разрешен прямой доступ к таблицам
- серия dbo.MyTable_ [OP] CRUD-хранимых процессов (_GET, _INSERT, _UPDATE и т. Д.)
- MyTable имеет столбец Timestamp с именем "ts"
Все процессы CRUD, где это уместно, включают параметр ввода / вывода @ts, чтобы избежать проблем параллелизма.
Я использую DevExpress WebForms GridView - работает отлично, не проблема.
GridView использует MS SqlDataSource. Его команда select вызывает процедуру MyTable_List. Его команда вставки вызывает метод MyTable_Insert. Оба из них работают безупречно.
Обновления нет. Работал в интернете, пытаясь понять, возможно ли это. Итак, обновление в основном таково:
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, сохраняя значение метки времени из БД в сеанс var, как и ожидалось (очевидно, что формат в .NET отличается от SQL). Когда я пытаюсь зафиксировать изменение (нажмите «обновить» в редакторе сетки DevEx »), ts_Updating запускается, весь код завершается без исключений. Затем, когда SqlDataSource запускает фактическое обновление, он выдает« Не удалось преобразовать значение параметра из Binary to Byte []. "в сетку DevEx и сообщает об этом через пользовательский интерфейс сетки.
Как я могу (возможно ли даже?) Перетасовать значение метки времени в базе данных в сеанс, а затем отправить его через параметр обновления SqlDataSource?
Опять же, я понимаю, что могу преодолеть это, выписав все CSLA или даже просто используя ObjectDataSource и выполнив всю логику обновления, но мне не хватает времени для нескольких сеток, которые мне просто нужно сделать и переместить на - большую рыбу в проекте жарить.
СПАСИБО!