9

dapper が TVF をサポートできることは知っていますが、TVF と共に追加のパラメーターを (IntDynamicParam クラスに追加せずに) どのように送信しますか? 以下の Tests.cs の例を参照してください。追加のパラメーターを追加するように変更しました。

connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
connection.Execute("CREATE PROC get_ints @x int, @ints int_list_type READONLY AS select * from @ints");

次のことを試しましたが、エラーが発生しました (オブジェクト型 SqlMapper.Tests+IntDynamicParam から既知のマネージド プロバイダー ネイティブ型へのマッピングは存在しません)。

var p = new DynamicParameters();
p.Add("x", 4);
p.Add("ints",new IntDynamicParam(new int[] { 1, 2, 3 }));

var nums = connection.Query<int>("get_ints", p).ToList();

サムさん、返信ありがとうございます。質問が少し違いました。タプルと一緒に別の変数を渡す方法を知りたいです。以下の変更された SP を参照してください。

CREATE TYPE int_tuple_list_type AS TABLE (n int NOT NULL PRIMARY KEY, n2 int)

CREATE PROC get_int_tuples 
  @someVar varchar(10),
  @ints int_tuple_list_type READONLY
AS select * from @ints
4

7 に答える 7

7

すぐに実行できるオープンIDbCommandにIDynamicParameters実装することだけを心配する必要があるので、魔法はほとんどありません。AddParameters

intのタプルが必要だとすると、次のように実装できます。

CREATE TYPE int_tuple_list_type 
     AS TABLE (n int NOT NULL PRIMARY KEY, n2 int)
CREATE PROC get_int_tuples @ints 
     int_tuple_list_type READONLY AS select * from @ints

に続く:

class TupleIntDynamicParam : Dapper.SqlMapper.IDynamicParameters
{
    IEnumerable<int> tuples;
    public IntDynamicParam(IEnumerable<Tuple<int,int>> tuples)
    {
        this.tuples= tuples;
    }

    public void AddParameters(IDbCommand command)
    {
        var sqlCommand = (SqlCommand)command;
        sqlCommand.CommandType = CommandType.StoredProcedure;

        List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = 
           new List<Microsoft.SqlServer.Server.SqlDataRecord>();

        // Create an SqlMetaData object that describes our table type.
        Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { 
          new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int), 
          new Microsoft.SqlServer.Server.SqlMetaData("n2", SqlDbType.Int) };

        foreach (int n in tuples)
        {
            // Create a new record, using the metadata array above.
            Microsoft.SqlServer.Server.SqlDataRecord rec = 
                new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
            rec.SetInt32(0, n.Item1);
            rec.SetInt32(1, n.Item2);
            number_list.Add(rec);      // Add it to the list.
        }

        // Add the table parameter.
        var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
        p.Direction = ParameterDirection.Input;
        p.TypeName = "int_tuple_list_type";
        p.Value = number_list;

    }
}

次に、次のタプルを渡すことができます。

var nums = connection.Query("get_int_tuples", 
      new TupleIntDynamicParam (new Tuple<int,int>[] 
      { 
           Tuple.Create(1,2), Tuple.Create(2,3) 
      })).ToList();
于 2011-08-19T06:02:36.283 に答える
3

これが、ジェネリッククラスを使用した方法です。これはまだ完璧ではありません。変更を加えたら、この投稿を更新します。

public class TableTypeDynamicParam<T> : Dapper.SqlMapper.IDynamicParameters
{
    IEnumerable<T> MyList;
    Dictionary<string, int> ordinals;
    Dictionary<Type, SqlDbType> typeMap;
    string ParameterName, TableTypeName;
    public TableTypeDynamicParam(IEnumerable<T> listValue, string parameterName, string tableTypeName)
    {
        this.MyList = listValue;
        this.ParameterName = parameterName;
        this.TableTypeName = tableTypeName;
        ordinals = new Dictionary<string, int>();
        SetTypeMap();
    }

    void SetTypeMap()
    {
        typeMap = new Dictionary<Type, SqlDbType>();
        typeMap[typeof(byte)] = SqlDbType.TinyInt;
        typeMap[typeof(sbyte)] = SqlDbType.TinyInt;
        typeMap[typeof(short)] = SqlDbType.SmallInt;
        typeMap[typeof(ushort)] = SqlDbType.SmallInt;
        typeMap[typeof(int)] = SqlDbType.Int;
        typeMap[typeof(uint)] = SqlDbType.Int;
        typeMap[typeof(long)] = SqlDbType.Int;
        typeMap[typeof(ulong)] = SqlDbType.BigInt;
        typeMap[typeof(float)] = SqlDbType.Float;
        typeMap[typeof(double)] = SqlDbType.Float;
        typeMap[typeof(decimal)] = SqlDbType.Decimal;
        typeMap[typeof(bool)] = SqlDbType.Bit;
        typeMap[typeof(string)] = SqlDbType.Text;
        typeMap[typeof(char)] = SqlDbType.Char;
        typeMap[typeof(Guid)] = SqlDbType.UniqueIdentifier;
        typeMap[typeof(DateTime)] = SqlDbType.DateTime;
        typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
        typeMap[typeof(byte[])] = SqlDbType.Binary;
        typeMap[typeof(byte?)] = SqlDbType.TinyInt;
        typeMap[typeof(sbyte?)] = SqlDbType.TinyInt;
        typeMap[typeof(short?)] = SqlDbType.SmallInt;
        typeMap[typeof(ushort?)] = SqlDbType.SmallInt;
        typeMap[typeof(int?)] = SqlDbType.Int;
        typeMap[typeof(uint?)] = SqlDbType.Int;
        typeMap[typeof(long?)] = SqlDbType.BigInt;
        typeMap[typeof(ulong?)] = SqlDbType.BigInt;
        typeMap[typeof(float?)] = SqlDbType.Float;
        typeMap[typeof(double?)] = SqlDbType.Float;
        typeMap[typeof(decimal?)] = SqlDbType.Decimal;
        typeMap[typeof(bool?)] = SqlDbType.Bit;
        typeMap[typeof(char?)] = SqlDbType.Char;
        typeMap[typeof(Guid?)] = SqlDbType.UniqueIdentifier;
        typeMap[typeof(DateTime?)] = SqlDbType.DateTime;
        typeMap[typeof(DateTimeOffset?)] = SqlDbType.DateTimeOffset;
        //  typeMap[typeof(System.Data.Linq.Binary)] = SqlDbType.Binary;
    }

    SqlDbType GetSqlDBType(Type t)
    {

        # region other tries

        /*  SqlParameter p1 = new SqlParameter();

             TypeConverter tc = TypeDescriptor.GetConverter(p1.DbType);
             if (tc.CanConvertFrom(theType))
                 p1.DbType = (DbType)tc.ConvertFrom(theType.Name);
             else
             {
                 //Try brute force
                 try
                 {
                     p1.DbType = (DbType)tc.ConvertFrom(theType.Name);
                 }
                 catch {} //Do Nothing
             }
             return p1.SqlDbType; 
             Microsoft.SqlServer.Server.SqlMetaData sm = Microsoft.SqlServer.Server.SqlMetaData.InferFromValue(new byte[] { 1, 2 }, "someName");
sm = Microsoft.SqlServer.Server.SqlMetaData.InferFromValue(2.3, "someName");
sm = Microsoft.SqlServer.Server.SqlMetaData.InferFromValue(11, "someName");
sm =     Microsoft.SqlServer.Server.SqlMetaData.InferFromValue(System.Web.HttpValidationStatus.Valid, "someName");
sm = Microsoft.SqlServer.Server.SqlMetaData.InferFromValue("hello", "someName");

Console.WriteLine(sm.SqlDbType);
Console.WriteLine(sm.TypeName);
Console.WriteLine(sm.MaxLength);

             */
        # endregion

        return typeMap[t];

    }

    void SetRecordValue(ref Microsoft.SqlServer.Server.SqlDataRecord rec, string propertyName, object value, Type propertyType)
    {
        switch (propertyType.ToString())
        {
            //need to cover all type case
            case "System.Int32":
                rec.SetInt32(ordinals[propertyName], (int)value);
                break;
            case "System.Int64":
                rec.SetInt64(ordinals[propertyName], (long)value);
                break;
            case "System.Boolean":
                rec.SetBoolean(ordinals[propertyName], (bool)value);
                break;
            case "System.String":
            default:
                rec.SetString(ordinals[propertyName], Convert.ToString(value));
                break;
        }
    }

    public void AddParameters(IDbCommand command)
    {
        var sqlCommand = (SqlCommand)command;
        sqlCommand.CommandType = CommandType.StoredProcedure;

        List<Microsoft.SqlServer.Server.SqlDataRecord> tableType_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
        var first = MyList.FirstOrDefault();
        if (null != first)
        {
            var lstDefinition = new List<Microsoft.SqlServer.Server.SqlMetaData>();
            int i = 0;
            foreach (var prop in first.GetType().GetProperties())
            {
                lstDefinition.Add(new Microsoft.SqlServer.Server.SqlMetaData(prop.Name, GetSqlDBType(prop.PropertyType)));
                ordinals.Add(prop.Name, i++);
            }
            // Create an SqlMetaData object that describes our table type.
            // Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };

            foreach (var l in MyList)
            {
                // Create a new record, using the metadata array above.
                Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(lstDefinition.ToArray());
                foreach (var prop in first.GetType().GetProperties())
                {

                    // rec.SetInt32(ordinals[prop.Name], prop.GetValue(l));    // Set the value.
                    SetRecordValue(ref rec, prop.Name, prop.GetValue(l), prop.GetType());
                }
                tableType_list.Add(rec);      // Add it to the list.
            }
        }

        // Add the table parameter.
        var p = sqlCommand.Parameters.Add("@" + ParameterName.TrimStart('@'), SqlDbType.Structured);
        p.Direction = ParameterDirection.Input;
        p.TypeName = TableTypeName;
        if (null != first)
            p.Value = tableType_list;
        else
            p.Value = DBNull.Value;

    }

    public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
    {
        AddParameters(command);
    }
}
于 2013-05-21T14:18:36.233 に答える
2

テーブル値パラメーターの使用を容易にするいくつかのクラスを含むnuget パッケージDapper TVPがあります。

パッケージは Dapper 1.12.1 以降に依存していることに注意してください。

このパッケージを使用してストアド プロシージャに tvp を渡すと、次のようになります。

        var p = new Dapper.Tvp.DynamicParametersTvp();

        SqlMetaData[] tableValuedParameterDefinition = 
        { 
            new SqlMetaData("columnOne", SqlDbType.UniqueIdentifier), 
            new SqlMetaData("columnTwo", SqlDbType.VarBinary, 64)
        };

        var collectionRows = new List<SqlDataRecord>();

        for (int i = 0; i < collection.Count; i++)
        {
            var row = new SqlDataRecord(tableValuedParameterDefinition);
            row.SetGuid(0, collection[i].Item1);
            row.SetBytes(1, 0, collection[i].Item2, 0, sessionsAndPins[i].Item2.Length);
            collectionRows.Add(row);
        }

        p.Add(new Dapper.Tvp.TableValueParameter("@tvpName", "tvpTypeName", collectionRows));

        using (SqlConnection connection = new SqlConnection(ConnectionManager.GetConnectionString("Database")))
        {
            try
            {
                connection.Open();

                result = connection.Query<SomeObject>("SomeStoredProcedureThatExpectsTVP", p, commandType: CommandType.StoredProcedure).SingleOrDefault();
            }
            finally
            {
                connection.Close();
            }
        }
于 2014-04-17T20:17:01.577 に答える
1

私はこれを行うことを好みます:

internal class TableTypeDynamicParam : SqlMapper.IDynamicParameters {
    protected readonly List<object> Lst = new List<object>();
    protected SqlCommand Cmd;
    public void Add(DataTable dt) {
        if(dt != null)
            Lst.Add(dt);
    }

    public void Add(DataSet ds) {
        if(ds != null)
            foreach(DataTable dt in ds.Tables) {
                Lst.Add(dt);
            }
    }

    public void Add(string name, object value = null, SqlDbType? dbType = null, ParameterDirection direction = ParameterDirection.Input, int? size = null) {
        var par = value != null ? new SqlParameter(name, value) : new SqlParameter(name, dbType);
        par.Direction = direction;
        if(size.HasValue)
            par.Size = size.Value;
        Lst.Add(par);
    }

    public void Add(SqlParameter par) {
        Lst.Add(par);
    }

    public void AddRange(IEnumerable<SqlParameter> pars) {
        if(pars != null)
            Lst.AddRange(pars);
    }

    public void AddParameters(IDbCommand command) {
        Cmd = (SqlCommand)command;

        foreach(var o in Lst) {
            var dt = o as DataTable;
            if(dt != null) {
                var parameter = Cmd.Parameters.AddWithValue(dt.ExtendedProperties["parameterName"].ToString(), dt);
                parameter.SqlDbType = SqlDbType.Structured;
                parameter.TypeName = dt.TableName;
            } else {
                var par = o as SqlParameter;
                if(par != null)
                    Cmd.Parameters.Add(par);
            }
        }
    }

    public void AddParameters(IDbCommand command, SqlMapper.Identity identity) {
        AddParameters(command);
    }

    public T Get<T>(string name) {
        return (T)Cmd.Parameters[name].Value;
    }

    public ERPDictionay GetLst(ERPLst<SqlParameter> pars) {
        var dic = new ERPDictionay();
        if(pars != null) {
            dic.QtdItemsPageParameterName = pars.QtdItemsPageParameterName;
            dic.QtdItemsPage = pars.QtdItemsPage;
            dic.CurrentPageParameterName = pars.CurrentPageParameterName;
            dic.CurrentPage = pars.CurrentPage;
        };
        for(var i = 0; i < Cmd.Parameters.Count; i++) {
            var a = Cmd.Parameters[i];
            if (a.Direction != ParameterDirection.InputOutput && a.Direction != ParameterDirection.Output) continue;
            if(pars != null && a.ParameterName == pars.TotalItensDBParameterName) {
                dic.TotalItensDB = Convert.ToInt32(Cmd.Parameters[i].Value);
            } else {
                dic.Add(a.ParameterName, Cmd.Parameters[i].Value);
            }
        }
        return dic;
    }
}

internal class TableTypeDynamicParam<T> : TableTypeDynamicParam
{
    private ERPLstInput<T> _lstItems;

    public void Add(ERPLstInput<T> lstItems)
    {
        if (lstItems != null)
            _lstItems = lstItems;
    }

    private static Dictionary<Type, SqlDbType> _typeMap;

    private static Dictionary<Type, SqlDbType> TypeMap
    {
        get
        {
            if (_typeMap != null)
                return _typeMap;
            _typeMap = new Dictionary<Type, SqlDbType>();
            _typeMap[typeof(byte)] = SqlDbType.TinyInt;
            _typeMap[typeof(sbyte)] = SqlDbType.TinyInt;
            _typeMap[typeof(short)] = SqlDbType.SmallInt;
            _typeMap[typeof(ushort)] = SqlDbType.SmallInt;
            _typeMap[typeof(int)] = SqlDbType.Int;
            _typeMap[typeof(uint)] = SqlDbType.Int;
            _typeMap[typeof(long)] = SqlDbType.Int;
            _typeMap[typeof(ulong)] = SqlDbType.BigInt;
            _typeMap[typeof(float)] = SqlDbType.Float;
            _typeMap[typeof(double)] = SqlDbType.Float;
            _typeMap[typeof(decimal)] = SqlDbType.Decimal;
            _typeMap[typeof(bool)] = SqlDbType.Bit;
            _typeMap[typeof(string)] = SqlDbType.Text;
            _typeMap[typeof(char)] = SqlDbType.Char;
            _typeMap[typeof(Guid)] = SqlDbType.UniqueIdentifier;
            _typeMap[typeof(DateTime)] = SqlDbType.DateTime;
            _typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
            _typeMap[typeof(byte[])] = SqlDbType.Binary;
            _typeMap[typeof(byte?)] = SqlDbType.TinyInt;
            _typeMap[typeof(sbyte?)] = SqlDbType.TinyInt;
            _typeMap[typeof(short?)] = SqlDbType.SmallInt;
            _typeMap[typeof(ushort?)] = SqlDbType.SmallInt;
            _typeMap[typeof(int?)] = SqlDbType.Int;
            _typeMap[typeof(uint?)] = SqlDbType.Int;
            _typeMap[typeof(long?)] = SqlDbType.BigInt;
            _typeMap[typeof(ulong?)] = SqlDbType.BigInt;
            _typeMap[typeof(float?)] = SqlDbType.Float;
            _typeMap[typeof(double?)] = SqlDbType.Float;
            _typeMap[typeof(decimal?)] = SqlDbType.Decimal;
            _typeMap[typeof(bool?)] = SqlDbType.Bit;
            _typeMap[typeof(char?)] = SqlDbType.Char;
            _typeMap[typeof(Guid?)] = SqlDbType.UniqueIdentifier;
            _typeMap[typeof(DateTime?)] = SqlDbType.DateTime;
            _typeMap[typeof(DateTimeOffset?)] = SqlDbType.DateTimeOffset;
            return _typeMap;
        }
    }

    static SqlDbType GetSqlDBType(Type t) {
        return TypeMap[t];
    }

    void SetRecordValue(ref SqlDataRecord rec, string propertyName, object value, Type propertyType) {
        switch(propertyType.ToString()) {
            case "System.Int32":
                rec.SetInt32(def.IndexOf(a=>a.Name == propertyName), (int)value);
                break;
            case "System.Int64":
                rec.SetInt64(def.IndexOf(a => a.Name == propertyName), (long)value);
                break;
            case "System.Boolean":
                rec.SetBoolean(def.IndexOf(a => a.Name == propertyName), (bool)value);
                break;
            case "System.String":
            default:
                rec.SetString(def.IndexOf(a => a.Name == propertyName), Convert.ToString(value));
                break;
        }
    }

    private List<SqlMetaData> def;
    public new void AddParameters(IDbCommand command) {
        Cmd = (SqlCommand)command;

        foreach(var o in Lst) {
            var dt = o as DataTable;
            if(dt != null) {
                var parameter = Cmd.Parameters.AddWithValue(dt.ExtendedProperties["parameterName"].ToString(), dt);
                parameter.SqlDbType = SqlDbType.Structured;
                parameter.TypeName = dt.TableName;
            } else {
                var par = o as SqlParameter;
                if(par != null)
                    Cmd.Parameters.Add(par);
            }
        }

        if (_lstItems != null)
        {
            var tableTypeList = new List<SqlDataRecord>();
            var first = _lstItems.FirstOrDefault();
            if (first != null)
            {
                def = new List<SqlMetaData>();
                int i = 0;
                foreach (var prop in first.GetType().GetProperties())
                {
                    def.Add(new SqlMetaData(prop.Name, GetSqlDBType(prop.PropertyType)));
                }
                foreach (var l in _lstItems)
                {
                    var rec = new SqlDataRecord(def.ToArray());
                    foreach (var prop in first.GetType().GetProperties())
                    {
                        SetRecordValue(ref rec, prop.Name, prop.GetValue(l), prop.GetType());
                    }
                    tableTypeList.Add(rec);
                }
            }

            var p = Cmd.Parameters.Add("@" + _lstItems.ParameterName.TrimStart('@'), SqlDbType.Structured);
            p.Direction = ParameterDirection.Input;
            p.TypeName = _lstItems.TableTypeName;
            if (null != first)
                p.Value = tableTypeList;
            else
                p.Value = DBNull.Value;
        }
    }
}

辞書は次のとおりです。

[Serializable]
public class ERPDictionay : Dictionary<string,object> {

    private string _currentPageParameterName = "@currentPage";
    public string CurrentPageParameterName {
        get { return _currentPageParameterName; }
        set { _currentPageParameterName = value; }
    }

    private string _qtdItemsPageParameterName = "@qtdItemsPage";
    public string QtdItemsPageParameterName {
        get { return _qtdItemsPageParameterName; }
        set { _qtdItemsPageParameterName = value; }
    }

    private string _totalItensDBParameterName = "@totalItensDB";
    public string TotalItensDBParameterName {
        get { return _totalItensDBParameterName; }
        set { _totalItensDBParameterName = value; }
    }

    public int CurrentPage { get; set; }
    public int QtdItemsPage { get; set; }
    public int TotalItensDB { get; set; }

    public ERPDictionay() { }

    public ERPDictionay(
        int qtdItemsPage,
        int currentPage = 0,
        string currentPageParameterName = null,
        string qtdItemsPageParameterName = null,
        string totalItensDBParameterName = null)
    {
        QtdItemsPage = qtdItemsPage;
        CurrentPage = currentPage;
        if (!string.IsNullOrEmpty(currentPageParameterName))
            _currentPageParameterName = currentPageParameterName;
        if(!string.IsNullOrEmpty(qtdItemsPageParameterName))
            _qtdItemsPageParameterName = qtdItemsPageParameterName;
        if(!string.IsNullOrEmpty(totalItensDBParameterName))
            _totalItensDBParameterName = totalItensDBParameterName;
    }
}
于 2014-03-15T18:49:39.810 に答える
1

テーブル値パラメーターと通常のパラメーターも渡すことができる必要がありました。@Esen と @Roger-Joys の回答を組み合わせると、以下のクラスが得られました。このクラスは特に stringlist_to_table タイプを使用することを目的としていますが、ニーズに合わせて変更できます。対処する TVP タイプごとに特定の方法を用意することは、私には理にかなっているように思えました。

CREATE TYPE stringlist_tbltype AS TABLE (s VARCHAR(256))

使用法:

var p = new DynamicParametersWithTVP();
p.Add( "@someVar", "abc", DbType.AnsiString );
p.AddTVPString( "@stringlist", new string[] { "abc", "def" } );

using (var conn = new SqlConnection( _cs )) {
    conn.Open();
    return conn.Query( "dbo.stored_proc_name", p, commandType: CommandType.StoredProcedure );
}

これが DynamicParametersWithTVP の実装です。基本的に、DynamicParameters クラスを保持して、TVP 以外のものを処理し、TVP 用にビルドします。

class DynamicParametersWithTVP : SqlMapper.IDynamicParameters
{
    private Dictionary<string, TVPData> _tvpParams;
    private DynamicParameters _params;

    public DynamicParametersWithTVP()
    {
        _tvpParams = new Dictionary<string, TVPData>();
        _params = new DynamicParameters();
    }

    public void Add( string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null )
    {
        _params.Add( name, value, dbType, direction, size );
    }

    public void AddTVPString( string name, IEnumerable<string> values )
    {
        var metadata = new[] {
            new SqlMetaData( "one", SqlDbType.VarChar, 256)
        };

        var data = new TVPData
        {
            Data = values,
            MetaData = metadata,
            Name = name,
            Type = "stringlist_tbltype",
            SetData = ( rec, s ) => rec.SetString( 0, (string)s ),
        };

        _tvpParams.Add( name, data );
    }

    public void AddParameters( IDbCommand command, SqlMapper.Identity identity )
    {
        //Adds the regular parameters, then adds any tvp parameters
        ((SqlMapper.IDynamicParameters)_params).AddParameters( command, identity );
        AddTVPCommands( command );
    }

    private void AddTVPCommands( IDbCommand command )
    {
        foreach (var o in _tvpParams) {
            AddTVPParam( command, o.Key, o.Value );
        }
    }

    private void AddTVPParam( IDbCommand command, string name, TVPData value )
    {
        var dataList = new List<SqlDataRecord>();
        if (value.Data != null) {
            foreach (var d in value.Data) {
                var rec = new SqlDataRecord( value.MetaData );
                value.SetData( rec, d ); //note: this only works for a one-column TVP
                dataList.Add( rec );
            }
        }
        if (dataList.Count == 0) { //gotta make the value null if there isn't any data.
            dataList = null;
        }

        var p = ((SqlCommand)command).Parameters.Add( name, SqlDbType.Structured );
        p.Direction = ParameterDirection.Input;
        p.TypeName = value.Type;
        p.Value = dataList;
    }

    private class TVPData
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public SqlMetaData[] MetaData { get; set; }
        public IEnumerable Data { get; set; }
        public Action<SqlDataRecord, object> SetData { get; set; }
    }
}
于 2013-07-25T17:50:42.653 に答える
0

DynamicParameters からカスタム クラスを派生させ、IDynamicParameters を実装すると、上記の問題を解決できます。

public class DynamicParametersWithTVP : Dapper.DynamicParameters, Dapper.SqlMapper.IDynamicParameters
{

.....

次のように proc を呼び出せる汎用クラスを作成しました。

        var procParams = new DynamicParametersWithTVP();
        procParams.Add("@Param1", someValue);
        procParams.Add("@Param2", someOtherValue);
        procParams.AddTVP("@TableParam1", "dbo.someTableType", someEnumberableListOfObject);
于 2013-02-08T05:06:25.587 に答える