Ho una procedura memorizzata con 3 parametri di input.
... PROCEDURE [dbo].[gama_SearchLibraryDocuments]
@Keyword nvarchar(160),
@CategoryIds [dbo].[IntList] READONLY,
@MarketIds [dbo].[IntList] READONLY ...
Dove IntList è il tipo di tabella definito dall'utente.
CREATE TYPE [dbo].[IntList]
AS TABLE ([Item] int NULL);
Il mio obiettivo è chiamare questa stored procedure con dapper.
Ho trovato alcuni esempi riguardanti il passaggio del tipo definito dall'utente con dapper. Uno di questi è la classe TableValuedParameter implementata nel pacchetto Dapper.Microsoft.Sql nuget.
var list = conn.Query<int>("someSP", new
{
Keyword = (string)null,
CategoryIds = new TableValuedParameter<int>("@CategoryIds", "IntList", new List<int> { }),
MarketIds = new TableValuedParameter<int>("@MarketIds", "IntList", new List<int> { 541 })
}, commandType: CommandType.StoredProcedure).ToList();
Scritto sopra il codice
An exception of type 'System.NotSupportedException' occurred in Dapper.dll but was not handled in user code
Additional information: The member CategoryIds of type Dapper.Microsoft.Sql.TableValuedParameter`1[System.Int32] cannot be used as a parameter value
Ho testato la mia stored procedure con un tipo di tabella definito dall'utente e ha funzionato correttamente.
conn.Query<int>("someSP", new TableValuedParameter<int>("@MarketIds", "IntList", new List<int> { 541 }), commandType: CommandType.StoredProcedure).ToList();
Ho bisogno di aiuto per eseguire la stored procedure originale. Grazie.
Dapper ha un metodo di estensione per lavorare con i parametri valutati in tabella.
public static SqlMapper.ICustomQueryParameter AsTableValuedParameter(this DataTable table, string typeName = null)
Puoi usare dapper nel seguente modo:
var providersTable = new DataTable();
providersTable.Columns.Add("value", typeof(Int32));
foreach (var value in filterModel.Providers)
{
providersTable.Rows.Add(value);
}
var providers = providersTable.AsTableValuedParameter("[dbo].[tblv_int_value]");
var filters =
new
{
campaignId = filterModel.CampaignId,
search = filterModel.Search,
providers = providers,
pageSize = requestContext.PageSize,
skip = requestContext.Skip
};
using (var query = currentConnection.QueryMultiple(StoredProcedureTest, filters, nhTransaction, commandType: CommandType.StoredProcedure))
{
var countRows = query.Read<int>().FirstOrDefault();
var temp = query.Read<CategoryModel>().ToList();
return new Result<IEnumerable<CategoryModel>>(temp, countRows);
}
Sarà tradotto in SQL:
declare @p3 dbo.tblv_int_value
insert into @p3 values(5)
insert into @p3 values(34)
insert into @p3 values(73)
insert into @p3 values(14)
exec [dbo].[StoredProcedureTest] @campaignId=123969,@search=NULL,@providers=@p3,@pageSize=20,@skip=0