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