using Knoks.Framework.Extentions; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; namespace Knoks.Framework.DataAccess { public static class DbMetaData { private const string storedProcedureParamsQuery = @"SELECT SPECIFIC_NAME,PARAMETER_MODE,PARAMETER_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.PARAMETERS P INNER JOIN sys.objects AS SO ON object_name(SO.OBJECT_ID) = P.SPECIFIC_NAME WHERE SO.type = 'P' ORDER BY SPECIFIC_NAME ASC,ORDINAL_POSITION ASC"; public static Dictionary> LoadParamMetaDataSet(string connectionString) { using (var conn = new SqlConnection(connectionString)) using (var cmd = new SqlCommand(storedProcedureParamsQuery, conn)) { conn.Open(); using (var reader = cmd.ExecuteReader()) { var procParams = new List(); var procName = string.Empty; var resultParams = new Dictionary>(StringComparer.OrdinalIgnoreCase); while (reader.Read()) { var param = ParamMetaData.LoadFromReader(reader); if (param.ProcName != procName) { if (procName != string.Empty) { resultParams.Add(procName, procParams); procParams = new List(); } procName = param.ProcName; } procParams.Add(param); } resultParams.Add(procName, procParams); return resultParams; } } } } public class ParamMetaData { public string ProcName { get; private set; } public string ParamName { get; private set; } public ParameterDirection Direction { get; private set; } public SqlDbType DataType { get; private set; } public int? Size { get; private set; } public SqlParameter GetSqlParameter(object value) { return new SqlParameter(ParamName, DataType) { Value = value ?? DBNull.Value, Size = Size ?? 0, Direction = Direction }; } public static ParamMetaData LoadFromReader(IDataReader reader) { return new ParamMetaData { ProcName = reader["SPECIFIC_NAME"].ToString(), ParamName = reader["PARAMETER_NAME"].ToString(), Direction = ConvertToDirection(reader["PARAMETER_MODE"].ToString()), DataType = ConvertToDataType(reader["DATA_TYPE"].ToString()), Size = Helper.GetNullableInt32(reader["CHARACTER_MAXIMUM_LENGTH"]) }; } private static SqlDbType ConvertToDataType(string dataTypeStr) { if (dataTypeStr == "table type") return SqlDbType.Structured; return dataTypeStr.ToEnum(); } private static ParameterDirection ConvertToDirection(string value) { switch (value) { case "IN": return ParameterDirection.Input; case "OUT": return ParameterDirection.Output; case "INOUT": return ParameterDirection.InputOutput; case "ReturnValue": return ParameterDirection.ReturnValue; default: throw new InvalidCastException($"Cast error. String value '{ value ?? "[null]" }' to { typeof(ParameterDirection) } type"); } } } }