Does Dapper support SQL 2008 Table-Valued Parameters? のコード よく働く。
しかし、MSSQL SQL_VARIANT 列には(通常)問題が発生します...
private static string ConnectionString = @"data source=192.168.1.1;initial catalog=;persist security info=False;user id=sa;password=";
private static void TestTVP2()
{
var connection = new SqlConnection(ConnectionString);
connection.Open();
var nums =
connection
.Query<BigIntKeySqlVariantValueType.TypeFields>("[dbo].[pmesAttributeValueUpdate]", new BigIntKeySQLVariantValueTVP(new[]
{
new BigIntKeySqlVariantValueType.TypeFields{ParameterName = 9976669, ParameterValue= 8.5}
}, "@tvp")
).ToList();
foreach (var num in nums)
{
Console.WriteLine(num.BigIntKeySqlVariantValueTypeId + " " + num.ParameterName + " " +
num.ParameterValue);
}
}
internal class BigIntKeySQLVariantValueTVP : SqlMapper.IDynamicParameters
{
private readonly IEnumerable<BigIntKeySqlVariantValueType.TypeFields> _values;
private readonly string _parametername;
public BigIntKeySQLVariantValueTVP(IEnumerable<BigIntKeySqlVariantValueType.TypeFields> values, string parametername)
{
this._values = values;
this._parametername = parametername;
}
public void AddParameters(IDbCommand command)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
var numberList = new List<SqlDataRecord>();
// Create an SqlMetaData object that describes our table type.
SqlMetaData[] tvpDefinition =
{
new SqlMetaData(
"BigIntKeySQLVariantValueTypeId", SqlDbType.BigInt, true, false, SortOrder.Unspecified, -1),
new SqlMetaData("ParameterName", SqlDbType.BigInt),
new SqlMetaData("ParameterValue", SqlDbType.Variant),
};
foreach (var n in _values)
{
// Create a new record, using the metadata array above.
var rec = new SqlDataRecord(tvpDefinition);
rec.SetInt64(1, n.ParameterName); // Set the value.
rec.SetValue(2, n.ParameterValue);
numberList.Add(rec); // Add it to the list.
}
// Add the table parameter.
var p = sqlCommand.Parameters.Add(_parametername, SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "BigIntKeySQLVariantValueType";
p.Value = numberList;
}
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
AddParameters(command);
}
}
public class BigIntKeySqlVariantValueType
{
/// <summary>
/// Type POCO
/// </summary>
public struct TypeFields
{
public long BigIntKeySqlVariantValueTypeId { get; private set; }
public long ParameterName { get; set; }
public object ParameterValue { get; set; }
}
}
以下は、SQL プロファイラーに表示される Dapper によって生成されたコードです。
declare @p1 dbo.BigIntKeySQLVariantValueType
insert into @p1 values(9976669,8,5)
exec [dbo].[pmesAttributeValueUpdate] @tvp=@p1
私のテーブル値型:
CREATE TYPE [dbo].[BigIntKeySQLVariantValueType] AS TABLE(
[BigIntKeySQLVariantValueTypeId] [bigint] IDENTITY(1,1) NOT NULL,
[ParameterName] [bigint] NULL,
[ParameterValue] [sql_variant] NULL,
PRIMARY KEY CLUSTERED
(
[BigIntKeySQLVariantValueTypeId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
Dapper によって生成されるコードは次のようになります。
insert into @p1 values(9976669,8.5)
コンマをドットに「置き換える」方法SqlParameter
// Add the table parameter.
var p = sqlCommand.Parameters.Add(_parametername, SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "BigIntKeySQLVariantValueType";
p.Value = numberList;