2
如果我有一個包含RowVersion列的SQLDataRecord,如下面的代碼所示。我總是得到一個SQL Server錯誤8052如何在調用存儲過程時在表值參數中包含RowVerson列?
傳入的表格數據流(TDS)遠程過程調用(RPC) 協議流不正確。表值參數%d(「%。* ls」),行 %I64d,列%d:數據類型0x%02X(用戶定義的表類型)時間戳 列需要爲缺省值。
是否將RowVersion值設置爲null或值。
我希望能夠爲現有記錄發送RowVersion值,並將ADO.NET中的新記錄發送到存儲過程,以便在合併記錄時使用optomistic併發檢查。
這怎麼辦?
namespace MyApplication.DataAccess
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Microsoft.SqlServer.Server;
public interface IRowVersionRecord
{
Byte[] RowVersionValue { get; set; }
Int32? Somevalue { get; set; }
}
public class RowVersionRecordBase : IRowVersionRecord
{
public Byte[] RowVersionValue { get; set; }
public Int32? Somevalue { get; set; }
public static IEnumerable<SqlDataRecord> CreateSqlDataRecordEnumerable(IEnumerable<IRowVersionRecord> dataTransferObjects)
{
var sqlMetaData = new SqlMetaData[]
{ new SqlMetaData("RowVersionValue", SqlDbType.Timestamp),
new SqlMetaData("somevalue", SqlDbType.Int)
};
var record = new SqlDataRecord(sqlMetaData);
foreach (var dto in dataTransferObjects)
{
record.SetValue(0, dto.RowVersionValue);
record.SetValue(1, dto.Somevalue);
yield return record;
}
}
}
public partial class RowVersionRecord : RowVersionRecordBase
{
}
}
namespace MyApplication.DataAccess
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
public abstract class RowVersionDAOBase : DAO
{
public virtual void Upsert(IEnumerable<RowVersionRecord> values)
{
using (var connection = Connection)
{
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "RowVersion_Upsert";
((SqlCommand)command).Parameters.Add("@values", SqlDbType.Structured).Value =
(object)RowVersionRecordBase.CreateSqlDataRecordEnumerable(values) ?? (object)DBNull.Value;
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess))
{
while (reader.NextResult())
{
///.....
}
}
}
}
}
}
public partial class RowVersionDAO : RowVersionDAOBase
{
}
}
//Test code snip
[TestMethod]
public void RowVersionTVPTest()
{
RowVersionRecord record = new RowVersionRecord();
record.Somevalue = 1;
List<RowVersionRecord> records = new List<RowVersionRecord>()
{
record
};
using (RowVersionDAO dao = new RowVersionDAO())
{
dao.Upsert(records);
}
}
我沒有在這裏得到的是,我可以有一個RowVersion作爲存儲過程的普通參數,我可以將一個值作爲一個字節傳遞給過程[8]。但是,如果我將TVP列聲明爲RowVersion,那麼我無法將該值指定爲byte [8]。我還沒有找到任何文檔說明在使用參數聲明時可以設置RowVersion類型,但不適用於TVP列。如果是這樣,爲什麼用戶定義的表類型有一個RowVersion列,如果它永遠不能被設置?或者可以和如何? –
@RichardCollette - 它遵循表的規則,而不是參數的規則,因爲這不應該令人驚訝 - 例如在用戶定義的表類型中不能包含* 2 * rowversion列,但可以創建兩個rowversion類型的參數並將其傳遞給存儲過程。如果您有UDTT的局部變量,則該表中的任何「INSERT」或「UPDATE」都將遵循通常的預期規則。 –
@Damien_TheUnbeliever我得到你對它的表現持續不變,但行爲不一致。在服務器上,您可以選擇一個UDTT,並將現有的行版本值複製到UDTT中。但是從ADO.NET中,我無法插入具有現有ROWVERSION值的行。不僅如此,但我無法指定傳遞給服務器的TVP行在RowVersion列中也有默認值。如果TVP是一個包含RowVersion列的UDTT,那麼TVP就不能在ADO.NET中使用(我還沒有看到它的一個例子)。 –