using System; using System.Data; using System.Reflection; #if !NETCOREAPP namespace Dapper { /// /// Used to pass a DataTable as a TableValuedParameter /// sealed class TableValuedParameter : SqlMapper.ICustomQueryParameter { private readonly DataTable table; private readonly string typeName; /// /// Create a new instance of TableValuedParameter /// public TableValuedParameter(DataTable table) : this(table, null) { } /// /// Create a new instance of TableValuedParameter /// public TableValuedParameter(DataTable table, string typeName) { this.table = table; this.typeName = typeName; } static readonly Action setTypeName; static TableValuedParameter() { var prop = typeof(System.Data.SqlClient.SqlParameter).GetProperty("TypeName", BindingFlags.Instance | BindingFlags.Public); if (prop != null && prop.PropertyType == typeof(string) && prop.CanWrite) { setTypeName = (Action) Delegate.CreateDelegate(typeof(Action), prop.GetSetMethod()); } } void SqlMapper.ICustomQueryParameter.AddParameter(IDbCommand command, string name) { var param = command.CreateParameter(); param.ParameterName = name; Set(param, table, typeName); command.Parameters.Add(param); } internal static void Set(IDbDataParameter parameter, DataTable table, string typeName) { #pragma warning disable 0618 parameter.Value = SqlMapper.SanitizeParameterValue(table); #pragma warning restore 0618 if (string.IsNullOrEmpty(typeName) && table != null) { typeName = table.GetTypeName(); } if (!string.IsNullOrEmpty(typeName)) { var sqlParam = parameter as System.Data.SqlClient.SqlParameter; if (sqlParam != null) { setTypeName?.Invoke(sqlParam, typeName); sqlParam.SqlDbType = SqlDbType.Structured; } } } } } #endif