Rufen Sie die gespeicherte Prozedur von dapper auf, die eine Liste mit benutzerdefinierten Tabellentypen akzeptiert

Ich habe eine gespeicherte ProzedurInsertCars Hiermit wird eine Liste mit benutzerdefinierten Tabellentypen akzeptiertCarType.

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

Ich muss diese gespeicherte Prozedur von Dapper aufrufen. Ich habe es gegoogelt und einige Lösungen gefunden.

 var param = new DynamicParameters(new{CARID= 66, CARNAME= "Volvo"});

 var result = con.Query("InsertCars", param, commandType: CommandType.StoredProcedure);

Aber ich bekomme einen Fehler:

In der Prozedur oder Funktion InsertCars wurden zu viele Argumente angegeben

Auch gespeicherte ProzedurInsertCars Gibt die Anzahl der eingefügten Zeilen zurück. Ich muss diesen Wert bekommen.

Wo liegt die Wurzel des Problems?

Mein Problem ist auch, dass ich Autos in der generischen Liste habeList<Car> Cars&nbsp;und ich möchte diese Liste weitergeben, um Prozedur zu speichern. Es gibt elegante Art und Weise, wie es geht?

public class Car
{
    public CarId { get; set; }
    public CarName { get; set; }
}

Danke für die Hilfe

BEARBEITET

Ich habe Lösungen gefunden

Unterstützt Dapper SQL 2008-Tabellenparameter?

oder

Unterstützt Dapper SQL 2008-Tabellenparameter 2?

Also versuche ich eine eigene dumme Helferklasse zu machen

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;
    }
}

Benutzen

var result = con.Query("InsertCars", new CarDynamicParam(car), commandType: CommandType.StoredProcedure);

Ich bekomme eine Ausnahme

Stellen Sie bei Verwendung der Multi-Mapping-APIs sicher, dass Sie den splitOn-Parameter festlegen, wenn Sie andere Schlüssel als Id haben.

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

Was ist falsch?

FEST:

Anrufcon.Execute&nbsp;stattdessencon.Query