Ho una procedura memorizzata InsertCars
che accetta l'elenco del tipo di tabella definito dall'utente CarType
.Procedura memorizzata chiamata da dapper che accetta l'elenco del tipo di tabella definito dall'utente
CREATE TYPE dbo.CarType
AS TABLE
(
CARID int null,
CARNAME varchar(800) not null,
);
CREATE PROCEDURE dbo.InsertCars
@Cars AS CarType READONLY
AS
-- RETURN COUNT OF INSERTED ROWS
END
Ho bisogno di chiamare questa stored procedure da Dapper. L'ho cercato su google e ho trovato alcune soluzioni.
var param = new DynamicParameters(new{CARID= 66, CARNAME= "Volvo"});
var result = con.Query("InsertCars", param, commandType: CommandType.StoredProcedure);
ma ottengo un errore:
Procedure or function InsertCars has too many arguments specified
memorizzata anche procedure InsertCars
restituisce il numero di righe inserite; Ho bisogno di ottenere questo valore.
Dove si trova la radice del problema?
Il mio problema è anche che ho le macchine nella lista generica List<Car> Cars
e voglio passare questa lista per memorizzare la procedura. Esiste un modo elegante come farlo?
public class Car
{
public CarId { get; set; }
public CarName { get; set; }
}
Grazie per l'aiuto
CURA
ho trovato soluzioni
Does Dapper support SQL 2008 Table-Valued Parameters?
o
Does Dapper support SQL 2008 Table-Valued Parameters 2?
quindi cerco fare propria classe di supporto stupido
class CarDynamicParam : Dapper.SqlMapper.IDynamicParameters
{
private Car car;
public CarDynamicParam(Car car)
{
this.car = car;
}
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
var carList = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
Microsoft.SqlServer.Server.SqlMetaData[] tvpDefinition =
{
new Microsoft.SqlServer.Server.SqlMetaData("CARID", SqlDbType.Int),
new Microsoft.SqlServer.Server.SqlMetaData("CARNAME", SqlDbType.NVarChar, 100),
};
var rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvpDefinition);
rec.SetInt32(0, car.CarId);
rec.SetString(1, car.CarName);
carList.Add(rec);
var p = sqlCommand.Parameters.Add("Cars", SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "CarType";
p.Value = carList;
}
}
Usa
var result = con.Query("InsertCars", new CarDynamicParam(car), commandType: CommandType.StoredProcedure);
ottengo un'eccezione
When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id.
StackTrace:
at Dapper.SqlMapper.GetDynamicDeserializer(IDataRecord reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in c:\Dev\Dapper\Dapper\SqlMapper.cs:line 1308
at Dapper.SqlMapper.GetDeserializer(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in c:\Dev\Dapper\Dapper\SqlMapper.cs:line 1141
at Dapper.SqlMapper.<QueryInternal>d__d`1.MoveNext() in c:\Dev\Dapper\Dapper\SqlMapper.cs:line 819
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in c:\Dev\Dapper\Dapper\SqlMapper.cs:line 770
at Dapper.SqlMapper.Query(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in c:\Dev\Dapper\Dapper\SqlMapper.cs:line 715
Cosa c'è che non va?
FISSO:
chiamata con.Execute
invece con.Query
Primo parametro passaggio problema ist a procedura di memorizzazione. Penso che il conteggio e l'ordine siano giusti. Metto alla prova la mia procedura tramite MS SQL Studio e funziona bene. Il tipo di tabella definito dall'utente ha solo 2 colonne, CARID e CARNAME. In DynamicParamater ho impostato solo queste due colonne. Quindi non capisco dove può essere un problema? – imodin
@Wobe ho menzionato il modo completo di farlo. per i parametri del tipo di tabella passo datatable come parametro e non come parametro dinamometrico – Ehsan