ASP.NET C#中如何按Status列降序排序DataSet内的DataTable
解决方案
方法一:通过DataView排序后生成新的DataTable
你之前的代码错误在于在填充DataSet之前就尝试操作DataView,此时Myds.Tables[0]还无数据,排序自然不生效。正确流程是先填充数据,再对DataTable的DefaultView设置排序规则,最后将排序后的DataView转为新DataTable:
修改后的完整代码:
[WebMethod(EnableSession = true)] public List<TaskListClass> getTasks() { var userId = Session["UserId"].ToString(); List<TaskListClass> objB = new List<TaskListClass>(); try { using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnString"].ToString())) { connection.Open(); DataSet Myds = new DataSet(); SqlDataAdapter sqldr = new SqlDataAdapter(); string ProcName = "getTasks"; SqlCommand cmd = new SqlCommand(ProcName, connection); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@userId", SqlDbType.VarChar, 900).Value = userId; sqldr.SelectCommand = cmd; sqldr.Fill(Myds); // 填充数据后处理排序 DataTable originalDt = Myds.Tables[0]; // 设置Status列降序排序 originalDt.DefaultView.Sort = "Status DESC"; // 将排序后的视图转为新DataTable DataTable sortedDt = originalDt.DefaultView.ToTable(); for (int i = 0; i < sortedDt.Rows.Count; i++) { objB.Add(new TaskListClass() { Id = Convert.ToString(sortedDt.Rows[i]["Id"]), Subject = Convert.ToString(sortedDt.Rows[i]["Subject"]), Customer = Convert.ToString(sortedDt.Rows[i]["Customer"]), Sender = Convert.ToString(sortedDt.Rows[i]["Sender"]), Receiver = Convert.ToString(sortedDt.Rows[i]["Receiver"]), Priority = Convert.ToString(sortedDt.Rows[i]["Priority"]), StartDate = Convert.ToString(sortedDt.Rows[i]["StartDate"]), EndDate = Convert.ToString(sortedDt.Rows[i]["EndDate"]), Status = Convert.ToString(sortedDt.Rows[i]["Status"]), OnProgress = Convert.ToString(sortedDt.Rows[i]["OnProgress"]), }); } } } catch (Exception e) { msg = e.ToString(); } return objB; }
方法二:直接对List排序
如果不需要保留DataTable的排序状态,也可以在数据转为List后直接排序,代码更简洁:
[WebMethod(EnableSession = true)] public List<TaskListClass> getTasks() { var userId = Session["UserId"].ToString(); List<TaskListClass> objB = new List<TaskListClass>(); try { using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnString"].ToString())) { connection.Open(); DataSet Myds = new DataSet(); SqlDataAdapter sqldr = new SqlDataAdapter(); string ProcName = "getTasks"; SqlCommand cmd = new SqlCommand(ProcName, connection); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@userId", SqlDbType.VarChar, 900).Value = userId; sqldr.SelectCommand = cmd; sqldr.Fill(Myds); DataTable dt = Myds.Tables[0]; for (int i = 0; i < dt.Rows.Count; i++) { objB.Add(new TaskListClass() { Id = Convert.ToString(dt.Rows[i]["Id"]), Subject = Convert.ToString(dt.Rows[i]["Subject"]), Customer = Convert.ToString(dt.Rows[i]["Customer"]), Sender = Convert.ToString(dt.Rows[i]["Sender"]), Receiver = Convert.ToString(dt.Rows[i]["Receiver"]), Priority = Convert.ToString(dt.Rows[i]["Priority"]), StartDate = Convert.ToString(dt.Rows[i]["StartDate"]), EndDate = Convert.ToString(dt.Rows[i]["EndDate"]), Status = Convert.ToString(dt.Rows[i]["Status"]), OnProgress = Convert.ToString(dt.Rows[i]["OnProgress"]), }); } // 对List按Status降序排序 objB = objB.OrderByDescending(t => t.Status).ToList(); } } catch (Exception e) { msg = e.ToString(); } return objB; }
额外优化建议
- 如果
Status是数值类型(如int),建议将TaskListClass中的Status属性也设置为对应数值类型,避免字符串排序的字典序偏差; - 最高效的方式是直接在存储过程
getTasks中添加ORDER BY Status DESC,让数据库直接返回排序后的数据,减少内存排序开销。
内容的提问来源于stack exchange,提问作者Emmon
相关产品推荐
相关产品推荐

