sql server - astablevaluedparameter - Usando Dapper.TVP TableValueParameter con otros parámetros
sql-server (2)
Basado en la respuesta de Mark Gravell aquí: ¿Dapper es compatible con los parámetros de valor de tabla de SQL 2008?
Cambié mi código para que ya no use Dapper.TVP y en su lugar solo use un DataTable
por lo que el código es ahora:
var recordsTable = new DataTable();
recordsTable.Columns.Add("NewValue", typeof(Decimal));
foreach (var netRevenue in records)
{
var row = recordsTable.NewRow();
row[0] = netRevenue.NewValue;
recordsTable.Rows.Add(row);
}
recordsTable.EndLoadData();
var spParams = new DynamicParameters(new
{
currentYear = filter.currentYear,
country = filter.country,
records = recordsTable.AsTableValuedParameter("Record_Table_Type")
});
using (var connection = ConnectionFactory.GetConnection())
{
connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);
}
Y esto funciona.
Tengo un procedimiento que toma un parámetro con valores de tabla, junto con otros:
CREATE PROCEDURE [dbo].[Update_Records]
@currentYear INT,
@country INT,
@records Record_Table_Type READONLY
AS
y estoy tratando de llamar a esto con Dapper.TVP.
Aquí está el código que tengo hasta ahora:
var recordsParameter = new List<SqlDataRecord>();
// This metadata matches ''Record_Table_Type'' in the Database
var recordsMetaData = new[]
{
new SqlMetaData("OriginalValue", SqlDbType.Decimal, 19, 4),
new SqlMetaData("NewValue", SqlDbType.Decimal, 19, 4),
new SqlMetaData("NewPercent", SqlDbType.Decimal, 7, 2),
};
foreach (var r in records)
{
var record = new SqlDataRecord(recordsMetaData);
record.SetDecimal(0, r.OriginalValue);
record.SetDecimal(1, r.NewValue);
record.SetDecimal(2, r.NewPercent);
recordsParameter.Add(record);
}
var spParams = new DynamicParameters(new
{
currentYear = filter.currentYear,
country = filter.country,
});
var recordsParam = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);
using (var connection = ConnectionFactory.GetConnection())
{
connection.Execute("Update_Records", ???, commandType: CommandType.StoredProcedure);
}
Mi problema es ¿cómo paso ambos conjuntos de parámetros al procedimiento en la llamada a Dapper Execute()
?
Yo he tratado:
var spParams = new DynamicParameters(new
{
currentYear = filter.currentYear,
country = filter.country,
records = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);
});
connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);
y
connection.Execute("Update_Records", new Object[] { spParams, recordsParam }, commandType: CommandType.StoredProcedure);
Ambos llaman al procedimiento, pero pasan un parámetro de tabla vacío ( SELECT COUNT(*) FROM @records
devuelve 0)
Parece que no puedo encontrar ninguna documentación o fuente real para Dapper.TVP, por lo que todo es muy confuso, y el segundo parámetro para .Execute()
es solo una dynamic
para que de nuevo no me diga lo que puedo y no se le puede pasar.
¿Algunas ideas?
Estoy en el móvil y puedo estar malinterpretando la pregunta, pero esto debería ser justo:
DataTable records = ...
connection.Execute("Update_Records",
new {
currentYear = filter.currentYear,
country = filter.country,
records
},
commandType: CommandType.StoredProcedure
);