Wywołaj procedurę przechowywaną z dappera, która akceptuje listę typów tabel zdefiniowanych przez użytkownika
Mam procedurę składowanąInsertCars
który akceptuje listę typów tabel zdefiniowanych przez użytkownikaCarType
.
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
Potrzebuję wywołać tę procedurę przechowywaną z Dappera. Wyszukałem go w Google i znalazłem kilka rozwiązań.
var param = new DynamicParameters(new{CARID= 66, CARNAME= "Volvo"});
var result = con.Query("InsertCars", param, commandType: CommandType.StoredProcedure);
Ale mam błąd:
Procedura lub funkcja InsertCars ma zbyt wiele określonych argumentów
Również procedura składowanaInsertCars
zwraca liczbę wstawionych wierszy; Potrzebuję tej wartości.
Gdzie jest źródło problemu?
Moim problemem jest także to, że mam samochody na ogólnej liścieList<Car> Cars
i chcę przekazać tę listę do przechowywania procedury. Istnieje elegancki sposób, aby to zrobić?
public class Car
{
public CarId { get; set; }
public CarName { get; set; }
}
Dziękuje Ci za pomoc
EDYCJA
Znalazłem rozwiązania
Czy Dapper obsługuje SQL 2008 Wartości tabelaryczne?
lub
Czy Dapper obsługuje SQL 2008 Wartości tabelaryczne Parametry 2?
Próbuję więc stworzyć własną głupią klasę pomocniczą
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;
}
}
Posługiwać się
var result = con.Query("InsertCars", new CarDynamicParam(car), commandType: CommandType.StoredProcedure);
Dostaję wyjątek
Podczas korzystania z interfejsów API z wieloma mapami upewnij się, że ustawiłeś parametr splitOn, jeśli masz klucze inne niż Id.
Ślad stosu:
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
Co jest nie tak?
NAPRAWIONY:
Połączeniecon.Execute
zamiastcon.Query