这个是为了后面我们使用T4模板生成存储过程的使用,这里单独拿出来学习
无参的存储过程这里就不演示了,这里演示有参的无输出的和有输出的这两种。
难点:我们可以把存储过程执行的结果填充到DataTable中,然后使用映射,把返回的字段映射到实体类,这需要我们的强类型中的字段和返回的结果集的列名保持一致,不区分大小写,或者使用逻辑让他们对应起来
注:QueryList2这个方法就实现了这一步, 映射对象 这篇介绍了一个实体映射到另一个实体,参考一下就完成了QueryList2这个方法
无输出参数存储过程
sql
IF OBJECT_ID('[TestPro2]') IS NOT NULL DROP PROCEDURE dbo.TestPro2; GO -- ============================================= -- Author: <sealee> -- Create date: <2019-01-29> -- Description: <测试无输出参数的存储过程> -- Example: EXEC dbo.TestPro2 @id = 1 -- ============================================= CREATE PROCEDURE [dbo].[TestPro2] (@id INT) AS SELECT * FROM dbo.tb_menu WHERE parent = @id; GO ;
执行结果:
代码:
string sqlcon = @"server=DESKTOP-UTQ1325\SQLSERVER2012;uid=sa;password=123;database=Test"; List<SqlParameter> parameters = new List<SqlParameter>(); string sql = " EXEC dbo.TestPro2 @id"; parameters.Add(new SqlParameter("@id", 1)); List<TestMapp> test = new Program().QueryList<TestMapp>(sqlcon, sql, parameters.ToArray()); //TestMapp是针对返回的结果创建的实体类
public class TestMapp { public int id { get; set; } public string title { get; set; } public int Parent { get; set; } }
public List<T> QueryList<T>(string conStr, string sql, SqlParameter[] parameters) where T : class, new() { return QueryList2<T>(conStr, sql, parameters); } public List<T> QueryList2<T>(string conStr, string sql, SqlParameter[] parameters) { List<T> result = new List<T>(); using (SqlConnection connection = new SqlConnection(conStr)) { connection.Open(); SqlCommand command = connection.CreateCommand(); command.CommandText = sql; command.Parameters.AddRange(parameters.ToArray()); SqlDataAdapter dataAdapter = new SqlDataAdapter(command); DataTable dt = new DataTable(); dataAdapter.Fill(dt); //执行的结构填充到我们的表格中 foreach (DataRow item in dt.Rows) { T d = Activator.CreateInstance<T>(); Type pp = typeof(T); PropertyInfo[] ppList = pp.GetProperties(); foreach (PropertyInfo pro in pp.GetProperties()) { Type s = pro.PropertyType; pro.SetValue(d, item[pro.Name], null);//进行数据映射 } result.Add(d); } } return result; }
运行结果:
有输出参数存储过程,这里定义的是单个输出参数
sql: 注意点:你的输出参数必须有个标识来标识他是输出参数
IF OBJECT_ID('[TestPro3]') IS NOT NULL DROP PROCEDURE dbo.[TestPro3]; GO -- ============================================= -- Author: <sealee> -- Create date: <2019-01-29> -- Description: <测试有返回参数> -- Example:DECLARE @Outtitle NVARCHAR(50);EXEC dbo.TestPro3 @id = 0,@Outtitle = @Outtitle OUTPUT -- ============================================= CREATE PROCEDURE [dbo].[TestPro3] ( @id INT, @Outtitle NVARCHAR(50) OUTPUT ) AS SELECT @Outtitle = title FROM dbo.tb_menu WHERE id = @id; SELECT * FROM dbo.tb_menu WHERE parent = @id; GO
结果:
DECLARE @Outtitle NVARCHAR(50);EXEC dbo.TestPro3 @id = 1,@Outtitle = @Outtitle OUTPUT ; select @Outtitle;
代码:我们需要在上面的方法上加个参数来保存输出参数的key和value
string sqlcon = @"server=DESKTOP-UTQ1325\SQLSERVER2012;uid=sa;password=123;database=Test"; List<SqlParameter> parameters = new List<SqlParameter>(); string sql = "EXEC dbo.TestPro3 @id,@Outtitle OUTPUT"; parameters.Add(new SqlParameter("@id", 1)); SqlParameter outPar = new SqlParameter("@Outtitle", SqlDbType.NVarChar, 100); outPar.Direction = ParameterDirection.Output; //标识为输出参数 parameters.Add(outPar); Dictionary<string, object> keys = new Dictionary<string, object>(); //用来存储输出参数 List<TestMapp> test = new Program().QueryList<TestMapp>(sqlcon, sql, parameters.ToArray(),keys); string returnString = keys["@Outtitle"].ToString();
public List<T> QueryList<T>(string conStr, string sql, SqlParameter[] parameters, Dictionary<string, object> keys = null) where T : class, new() { return QueryList2<T>(conStr, sql, parameters, keys); } public List<T> QueryList2<T>(string conStr, string sql, SqlParameter[] parameters, Dictionary<string, object> keys = null) { List<T> result = new List<T>(); using (SqlConnection connection = new SqlConnection(conStr)) { connection.Open(); SqlCommand command = connection.CreateCommand(); command.CommandText = sql; command.Parameters.AddRange(parameters.ToArray()); SqlDataAdapter dataAdapter = new SqlDataAdapter(command); DataTable dt = new DataTable(); dataAdapter.Fill(dt);//执行的结构填充到我们的表格中 foreach (SqlParameter item in parameters) { if (item.ParameterName.Contains("Out")) //根据你sql的标识来确定输出参数 { //这里存object类型,使用的时候自己需要转型 keys[item.ParameterName] = command.Parameters[item.ParameterName].Value; } } foreach (DataRow item in dt.Rows) { T d = Activator.CreateInstance<T>(); Type pp = typeof(T); PropertyInfo[] ppList = pp.GetProperties(); foreach (PropertyInfo pro in pp.GetProperties()) { Type s = pro.PropertyType; pro.SetValue(d, item[pro.Name], null);//进行数据映射 } result.Add(d); } } return result; }
结果:
如果有输出参数你就传一个字典类型,如果没有输出参数你就不用传字典类型