¿Hay alguna manera de pasar un TVP para apostar en .Net Core en este momento?

Estoy usando .net core y dapper, el primero no tiene DataTables y el segundo los usa para TVP.

Estaba tratando de convertir unList<T> a unList<SqlDataRecord>, cree un SqlParameter con esta lista y luego conviértalo en un DynamicParameter pero lamentablemente obtuve un:The member of type Microsoft.SqlServer.Server.SqlDataRecord cannot be used as a parameter value

ACTUALIZAR

Después de jugar un poco conIDynamicParametersLo hice funcionar.

Método de extensión paraIEnumerable

public static DynamicWrapper toTVP<T>(this IEnumerable<T> enumerable, string tableName, string typeName)
{
    List<SqlDataRec,ord> records = new List<SqlDataRecord>();
    var properties = typeof(T).GetProperties().Where(p => Mapper.TypeToSQLMap.ContainsKey(p.PropertyType));
    var definitions = properties.Select(p => Mapper.TypeToMetaData(p.Name, p.PropertyType)).ToArray();
    foreach (var item in enumerable)
    {
        var values = properties.Select(p => p.GetValue(item, null)).ToArray();
        var schema = new SqlDataRecord(definitions);
        schema.SetValues(values);
        records.Add(schema);
    }

    SqlParameter result = new SqlParameter(tableName, SqlDbType.Structured);
    result.Direction = ParameterDirection.Input;
    result.TypeName = typeName;
    result.Value = records;
    return new DynamicWrapper(result);
}

Contenedor para implementarIDynamicParameters

public class DynamicWrapper : IDynamicParameters
{
    private readonly SqlParameter _Parameter;
    public DynamicWrapper(SqlParameter param)
    {
        _Parameter = param;
    }

    public void AddParameters(IDbCommand command, Identity identity)
    {
        command.Parameters.Add(_Parameter);
    }
}

Mapper (no completamente probado, solo administró una cadena a NVARCHAR porque arroja una excepción sinmaxLength)

public class Mapper
{
    public static Dictionary<Type, SqlDbType> TypeToSQLMap = new Dictionary<Type, SqlDbType>()
        {
              {typeof (long),SqlDbType.BigInt},
              {typeof (long?),SqlDbType.BigInt},
              {typeof (byte[]),SqlDbType.Image},
              {typeof (bool),SqlDbType.Bit},
              {typeof (bool?),SqlDbType.Bit},
              {typeof (string),SqlDbType.NVarChar},
              {typeof (DateTime),SqlDbType.DateTime2},
              {typeof (DateTime?),SqlDbType.DateTime2},
              {typeof (decimal),SqlDbType.Money},
              {typeof (decimal?),SqlDbType.Money},
              {typeof (double),SqlDbType.Float},
              {typeof (double?),SqlDbType.Float},
              {typeof (int),SqlDbType.Int},
              {typeof (int?),SqlDbType.Int},
              {typeof (float),SqlDbType.Real},
              {typeof (float?),SqlDbType.Real},
              {typeof (Guid),SqlDbType.UniqueIdentifier},
              {typeof (Guid?),SqlDbType.UniqueIdentifier},
              {typeof (short),SqlDbType.SmallInt},
              {typeof (short?),SqlDbType.SmallInt},
              {typeof (byte),SqlDbType.TinyInt},
              {typeof (byte?),SqlDbType.TinyInt},
              {typeof (object),SqlDbType.Variant},
              {typeof (DataTable),SqlDbType.Structured},
              {typeof (DateTimeOffset),SqlDbType.DateTimeOffset}
        };

    public static SqlMetaData TypeToMetaData(string name, Type type)
    {
        SqlMetaData data = null;

        if (type == typeof(string))
        {
            data = new SqlMetaData(name, SqlDbType.NVarChar, -1);
        }
        else
        {
            data = new SqlMetaData(name, TypeToSQLMap[type]);
        }

        return data;
    }
}

Tipo de SQL para mi ejemplo:

CREATE TYPE TestType AS TABLE ( 
    FirstName NVARCHAR(255)  
    , GamerID INT 
    , LastName NVARCHAR(255)
    , Salt UNIQUEIDENTIFIER);  
GO  

Utilizándolo:

List<Gamer> gamers = new List<Gamer>();

gamers.Add(new Gamer {
                Email = new string[] { "[email protected]" },
                FirstName = "Test_F0",
                LastName = "Test_L0",
                GamerID = 0,
                Salt = Guid.NewGuid()});

            gamers.Add(new Gamer {
                Email = new string[] { "[email protected]" },
                FirstName = "Test_F1",
                LastName = "Test_L1",
                GamerID = 1,
                Salt = Guid.NewGuid()});

            var structured = gamers.toTVP("GamerTable", "dbo.TestType");

            using (var con = new SqlConnection(TestConnectionString))
            {
                con.Open();

                string query = @"

                SELECT * 
                FROM @GamerTable t
                WHERE t.GamerID = 1

                ";

var result = con.Query(query, structured);

//var result = con.Query("dbo.DapperTest", structured, commandType: CommandType.StoredProcedure);

Como puede ver, el modelo eliminó la matriz de cadenas para correos electrónicos, porque no lo codifiqué para tener tvp anidado. (TypeToSQLMap.ContainsKey parte), pero podría codificarse, cambiando el contenedor para aceptar un número enumerable de parámetros y AddParameters para foreach y agregarlos. Se trata más de un problema con los nombres de los tipos, etc. Estaba pensando en crear algunos tipos genéricos nombrados en función de los tipos de propiedad. Por ahora, esto es suficiente, no dude en actualizarlo si no lo hago.

Hoy intentaré mejorarlo un poco más.

Respuestas a la pregunta(1)

Su respuesta a la pregunta