【问题标题】:Return Result from Select Query in stored procedure to a List将存储过程中选择查询的结果返回到列表
【发布时间】:2013-09-24 22:38:07
【问题描述】:

我正在编写一个当前仅包含SELECT 查询的存储过程。它将被扩展来做一些其他的事情,这就是为什么它必须是一个存储过程,但现在,它是一个简单的查询。

类似这样的:

SELECT name, occupation, position 
FROM jobs 
WHERE ...

我希望返回此查询的结果以在 C# 中使用。我想将它添加到列表中,以便可以将其绑定到 GridView 组件。

不过,我不知道该怎么做。如果我必须在返回所有选定的数据后将其插入到列表中,那没关系,我只需要知道如何正确返回数据以便我可以做到这一点。

如果我能以一种可以直接弹出到列表中的格式返回它,那将是理想的。

【问题讨论】:

  • 为什么必须是列表?返回一个标准的 ADO.NET 组件(DataTable、DataReader)并将您的网格绑定到它。网上有很多教程如何做到这一点。例如。做google.com/search?q=C%23+ADO.NET+GridView+Bind 你会看到很多类似java2s.com/Code/ASP/ADO.net-Database/…的东西
  • 那将是一个更好的解决方案!不过,我将不得不研究如何从存储过程中返回这些行。你知道怎么做吗?
  • 看看第二个链接中的示例 - 它就是这样做的 - 打开连接,检索数据并将其绑定到 GridView1。它使用 SELECT 查询,但很容易调整以处理存储过程。
  • 是的,我的意思是存储过程代码本身。我不知道我是否应该以某种方式在 SELECT 查询上使用 RETURN,或者......我似乎找不到这个。
  • 不,如果您想返回多行(不是单个值),存储过程中的最后一个命令应该是 SELECT - 结果将返回到 C# 代码。

标签: c# asp.net sql-server


【解决方案1】:
SqlConnection con = new SqlConnection("Data Source=DShp;Initial Catalog=abc;Integrated Security=True");
SqlDataAdapter da = new SqlDataAdapter("data", con);

da.SelectCommand.CommandType= CommandType.StoredProcedure;

DataSet ds=new DataSet();

da.Fill(ds, "data");
GridView1.DataSource = ds.Tables["data"];
GridView1.DataBind();

【讨论】:

    【解决方案2】:

    在存储过程中,你只需要编写如下的选择查询:

    CREATE PROCEDURE TestProcedure
    AS
    BEGIN
        SELECT ID, Name 
        FROM Test
    END
    

    在 C# 端,您可以使用 Reader、数据表、适配器进行访问。

    Susanna Floora 刚刚解释了使用适配器。

    使用阅读器:

    SqlConnection connection = new SqlConnection(ConnectionString);
    
    command = new SqlCommand("TestProcedure", connection);
    command.CommandType = System.Data.CommandType.StoredProcedure;
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    
    List<Test> TestList = new List<Test>();
    Test test = null;
    
    while (reader.Read())
    {
        test = new Test();
        test.ID = int.Parse(reader["ID"].ToString());
        test.Name = reader["Name"].ToString();
        TestList.Add(test);
    }
    
    gvGrid.DataSource = TestList;
    gvGrid.DataBind();
    

    使用数据表:

    SqlConnection connection = new SqlConnection(ConnectionString);
    
    command = new SqlCommand("TestProcedure", connection);
    command.CommandType = System.Data.CommandType.StoredProcedure;
    connection.Open();
    
    DataTable dt = new DataTable();
    
    dt.Load(command.ExecuteReader());
    gvGrid.DataSource = dt;
    gvGrid.DataBind();
    

    希望对你有所帮助。 :)

    【讨论】:

    • 我会添加reader.Close(),有时打开阅读器会导致以下代码出现异常。
    • 这只是一个例子,但是你应该总是在 finally 块中清理这些东西,包括 sqlconnection。
    • 给出的两个示例中哪一个对于较大的数据集最有效?
    • 数据绑定不可用?
    • 如果您在上面的示例中指的是网格的 DataBind() 方法,那么它应该在 web 项目中可用,而在其他项目(如 windows 应用程序)中可用的网格中不需要。
    【解决方案3】:
     SqlConnection connection = new SqlConnection(ConnectionString);
    
     command = new SqlCommand("TestProcedure", connection);
     command.CommandType = System.Data.CommandType.StoredProcedure;
    
     connection.Open();
    
     DataTable dt = new DataTable();
    
     dt.Load(command.ExecuteReader());
    
     gvGrid.DataSource = dt;
     gvGrid.DataBind();
    

    【讨论】:

      【解决方案4】:

      我有同样的问题,我花了很长时间才找到一个简单的解决方案。

      使用 ASP.NET MVC 5 和 EF 6:

      当您向 .edmx 模型添加存储过程时,存储过程的结果将通过名为 yourStoredProcName_result 的自动生成对象传递。

      _result 对象包含与您的存储过程选择的数据库中的列相对应的属性。

      _result 类可以简单地转换为列表:

      yourStoredProcName_result.ToList()
      

      【讨论】:

        【解决方案5】:

        这可能会有所帮助:

        从数据库中获取行:

        public static DataRowCollection getAllUsers(string tableName) 
        {
             DataSet set = new DataSet();
             SqlCommand comm = new SqlCommand();
             comm.Connection = DAL.DAL.conn;
             comm.CommandType = CommandType.StoredProcedure;
             comm.CommandText = "getAllUsers";
             SqlDataAdapter da = new SqlDataAdapter();
             da.SelectCommand = comm;
             da.Fill(set,tableName);
        
             DataRowCollection usersCollection = set.Tables[tableName].Rows;
             return usersCollection;
        }
        

        从 DataRowCollection 填充 DataGridView :

        public static void ShowAllUsers(DataGridView grdView,string table, params string[] fields) 
        {
            DataRowCollection userSet = getAllUsers(table);
            foreach (DataRow user in userSet)
            {
                 grdView.Rows.Add(user[fields[0]],
                 user[fields[1]],
                 user[fields[2]],
                 user[fields[3]]);
            }
        }
        

        实施:

        BLL.BLL.ShowAllUsers(grdUsers,"eusers","eid","euname","eupassword","eposition");
        

        【讨论】:

          【解决方案6】:

          在存储过程中传递参数并在后面的C#代码中调用它如下所示?

          SqlConnection conn = new SqlConnection(func.internalConnection);
          var cmd = new SqlCommand("usp_CustomerPortalOrderDetails", conn);
          cmd.CommandType = System.Data.CommandType.StoredProcedure;
          cmd.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
          cmd.Parameters.Add("@Qid", SqlDbType.VarChar).Value = qid;
          conn.Open();
          
          // Populate Production Panels
          DataTable listCustomerJobDetails = new DataTable();
          listCustomerJobDetails.Load(cmd.ExecuteReader());
          conn.Close();
          

          【讨论】:

            【解决方案7】:
            // GET: api/GetStudent
            
            public Response Get() {
                return StoredProcedure.GetStudent();
            }
            
            public static Response GetStudent() {
                using (var db = new dal()) {
                    var student = db.Database.SqlQuery<GetStudentVm>("GetStudent").ToList();
                    return new Response {
                        Sucess = true,
                        Message = student.Count() + " Student found",
                        Data = student
                    };
                }
            }
            

            【讨论】:

            • 嗨@sachin,欢迎来到堆栈溢出,请提供一些简短的描述,以便操作员更好地理解
            【解决方案8】:

            基于此处的一些响应,我想添加一种替代方式。使用反射创建一个通用方法,该方法可以将任何存储过程响应映射到列表。也就是说,您希望的任何类型的列表,只要给定类型包含与响应中的存储过程列类似的名称成员。 理想情况下,我可能会为此使用 Dapper - 但这里是:

            private static SqlConnection getConnectionString() // Should be gotten from config in secure storage.
                    {
                        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
                        builder.DataSource = "it.hurts.when.IP";
                        builder.UserID = "someDBUser";
                        builder.Password = "someDBPassword";
                        builder.InitialCatalog = "someDB";
                        return new SqlConnection(builder.ConnectionString);
                    }
            
                    public static List<T> ExecuteSP<T>(string SPName, List<SqlParameter> Params)
                    {
                        try
                        {
                            DataTable dataTable = new DataTable();
            
                            using (SqlConnection Connection = getConnectionString())
                            {
                                // Open connection
                                Connection.Open();
            
                                // Create command from params / SP
                                SqlCommand cmd = new SqlCommand(SPName, Connection);
            
                                // Add parameters
                                cmd.Parameters.AddRange(Params.ToArray());
                                cmd.CommandType = CommandType.StoredProcedure;
            
                                // Make datatable for conversion
                                SqlDataAdapter da = new SqlDataAdapter(cmd);
                                da.Fill(dataTable);
                                da.Dispose();
            
                                // Close connection
                                Connection.Close();
                            }
            
                            // Convert to list of T
                            var retVal = ConvertToList<T>(dataTable);
                            return retVal;
                        }
                        catch (SqlException e)
                        {
                            Console.WriteLine("ConvertToList Exception: " + e.ToString());
                            return new List<T>();
                        }
                    }
            
                    /// <summary>
                    /// Converts datatable to List<someType> if possible.
                    /// </summary>
                    public static List<T> ConvertToList<T>(DataTable dt)
                    {
                        try // Necesarry unfotunately.
                        {
                            var columnNames = dt.Columns.Cast<DataColumn>()
                                .Select(c => c.ColumnName)
                                .ToList();
            
                            var properties = typeof(T).GetProperties();
            
                            return dt.AsEnumerable().Select(row =>
                                {
                                    var objT = Activator.CreateInstance<T>();
            
                                    foreach (var pro in properties)
                                    {
                                        if (columnNames.Contains(pro.Name))
                                        {
                                            if (row[pro.Name].GetType() == typeof(System.DBNull)) pro.SetValue(objT, null, null);
                                            else pro.SetValue(objT, row[pro.Name], null);
                                        }
                                    }
            
                                    return objT;
                                }).ToList();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Failed to write data to list. Often this occurs due to type errors (DBNull, nullables), changes in SP's used or wrongly formatted SP output.");
                            Console.WriteLine("ConvertToList Exception: " + e.ToString());
                            return new List<T>();
                        }
                    }
            

            要点:https://gist.github.com/Big-al/4c1ff3ed87b88570f8f6b62ee2216f9f

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-04-23
              • 2020-04-02
              • 1970-01-01
              • 2022-01-08
              • 2012-07-15
              • 2011-02-20
              • 1970-01-01
              相关资源
              最近更新 更多