存储过程的输出接受强类

这个是为了后面我们使用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-UTQ1325SQLSERVER2012;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-UTQ1325SQLSERVER2012;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;
        }

结果:

 如果有输出参数你就传一个字典类型,如果没有输出参数你就不用传字典类型

原文地址:https://www.cnblogs.com/Sea1ee/p/10334339.html