C#对DataTable里数据筛选排序的方法
在日常开发过程中,有一个DataTable集合,里面有很多字段,现在要求针对某一列进行排序,如果该列为数字的话,进行ASC即可实现,但是该字段类型为string,此时排序就有点不正确了
protected void Page_Load(object sender, EventArgs e) { DataTable dt = new DataTable(); dt.Columns.Add("Name"); dt.Columns.Add("Age");//因为是字符串,所以排序不对 dt.Rows.Add("小明", "21"); dt.Rows.Add("小张", "10"); dt.Rows.Add("小红", "9"); dt.Rows.Add("小伟", "7"); dt.Rows.Add("小美", "3"); dt.DefaultView.Sort = "Age ASC"; dt = dt.DefaultView.ToTable(); foreach (DataRow s in dt.Rows) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); } Response.Write("------------------1----------------<br/>"); #region 方法1:将年龄补齐为2位,然后再进行排序,但是实际不应该有0(仅作参考) for (int i = 0; i < dt.Rows.Count; i++) { dt.Rows[i]["Age"] = dt.Rows[i]["Age"].ToString().PadLeft(2, '0'); } dt.DefaultView.Sort = "Age ASC"; dt = dt.DefaultView.ToTable(); foreach (DataRow s in dt.Rows) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); } #endregion Response.Write("------------------2----------------<br/>"); #region 方法2:创建新的DataTable,将Age类型变更为int类型 DataTable dtNew = dt.Clone(); dtNew.Columns["Age"].DataType = typeof(int);//指定Age为Int类型 foreach (DataRow s in dt.Rows) { dtNew.ImportRow(s);//导入旧数据 } dtNew.DefaultView.Sort = "Age ASC"; dtNew = dtNew.DefaultView.ToTable(); foreach (DataRow s in dtNew.Rows) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); } #endregion Response.Write("-----------------3-----------------<br/>"); #region 方法3:添加一列,主要用于排序 dt.Columns.Add("AgeLength", typeof(int), "len(Age)");//添加该列时,DataTable列数据即生成 dt.DefaultView.Sort = "AgeLength,Age ASC"; dt = dt.DefaultView.ToTable(); foreach (DataRow s in dt.Rows) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); } #endregion Response.Write("-----------------4-----------------<br/>"); #region 方法4:运用LinQ,将DataTable转换为集合,再调用集合自带的排序方法进行排序 foreach (DataRow s in dt.Rows.Cast<DataRow>().OrderBy(r => int.Parse(r["Age"].ToString()))) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); } #endregion }
DataTable dataTable;
1、排序
1.1、利用查询排序
DataRow[] dataRows = dataTable.Select("条件", "id asc"); //或多列排序 DataRow[] dataRows = dataTable.Select("条件", "id asc,name asc,..."); //对所有的进行排序 DataRow[] dataRows = dataTable.Select("1=1", "id asc,name asc,...");
1.2、默认视图排序
DataView dataView = dataTable.DefaultView; dataView.Sort = "id asc"; dataTable = dataView.ToTable();
2、搜索
如果单纯搜索,
DataRow[] dataRows = dataTable.Select("条件"); //或者 int id; string name; DataRow[] dataRows = dataTable.Select(string.Format(@"id={0} and name={1}",id,name));
如果对搜索结果排序,如同1.1。
说明:select方法如同sql语句对单表的查询,条件如同sql语句的where之后的部分,>,<,=,LIKE等都可以使用。
3、合并
合并的对象必须结构要一致,如果不一致先转换一致。然后,利用Merge方法,
DataTable dataTable1 = null; DataTable dataTable2 = null; dataTable1.Merge(dataTable2);
相关的DataTable的操作有,
行的初始化:http://blog.csdn.net/yysyangyangyangshan/article/details/7021107。
数组转DataTable:http://blog.csdn.net/yysyangyangyangshan/article/details/6947024。
LINQ的基础查询(使用LINQ to Object)
在此之前,我们先创建一个用于示例的数据源:
- Student类:表示学生,包括学号、姓名及班级
- Courses类:表示学生选择的课程,包括学号、课程名称及学时数
- DataCreator类:静态类,通过GenerateData方法产生示例数据
- 生成的数据如下:
学号 姓名 班级 课程名称 学时
003 王五 二班 经济学 20
003 王五 二班 企业管理 20
003 王五 二班 财务管理 30
002 李四 一班 历史 20
002 李四 一班 政治 20
002 李四 一班 语文 30
001 张三 一班 数学 20
001 张三 一班 语文 20
001 张三 一班 物理 15Main方法中生成数据:
-
List<Student> students = new List<Student>(); List<Courses> courses = new List<Courses>(); DataCreator.GenerateData(students, courses);
-
筛选
LINQ中通过where子句筛选数据,where子句后跟条件,from后的对象都可作为where子句判断条件的主体。
-
实际上from .. in ..语句类似于foreach语句,比如
-
from student in students 类似于 foreach(Student student in students)
-
student是students集合中的元素,那么通常在where语句中,可以使用student作为判断的依据,例如:
-
筛选出一班的所有学生:
-
var query = from student in students where student.Class == "一班" select student; foreach (var s in query) { Console.WriteLine(s); }
-
筛选学时大于等于20的课程:
-
var query = from course in courses where course.Credit >= 20 select course;
-
可使用&&或||来连接多个条件,如筛选出一班姓张的同学:
-
当然,并不是说条件语句中只能使用from后的对象,它可以使用任何对象作为判断依据(下面LINQ只作演示没实际意义):条件当前时间等于当前时间,此条件永远为真,故会查询出所有的学生资料。
-
var query = from student in students where DateTime.Now == DateTime.Now select student;
- 下例以students集合的数量作为判断条件,当stuents的数量大于等于3时筛选出所有学生资料:
-
var query = from student in students where students.Count>=3 select student;
-
下例筛选学号存在于ids集合中的学生:
-
String[] ids = {"001","003" }; var query = from student in students where ids.Contains(student.ID) select student;
-
查询选修了语文课程的学生资料:
-
var query = from student in students where (from cours in courses where cours.Name == "语文" select cours.StudentId).Contains(student.ID) select student; foreach (var s in query) { Console.WriteLine(s); }
-
注意上例中使用了嵌套查询,students where语句中包含另一个LINQ语句,该语句从courses集合中返回选修了语文课程的学号,它是一个IEnumerable<String>集合,所以可以在此集合上使用IEnumerable的Contains方法,判断集合中是否包含当前student对象的ID,包含则返回true,即students的where语句为真,该student对象被添加入结果集合,反之不添加。
-
排序
排序语句比较简单,基本语法为:
orderby .. ascending | descending[, ..ascending | descending]
其中ascending表示升序排列,descending表示降序排列
var query = from student in students orderby student.ID ascending /*descending*/ select student;
可根据多个字段进行排序:
var query = from student in students orderby student.ID ascending,student.Name descending select student;
以下源码产生示例数据:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LinqStudy { public static class DataCreator { public static void GenerateData(List<Student> students,List<Courses> courses) { students.Add(new Student("001","张三", "一班")); students.Add(new Student("002", "李四", "一班")); students.Add(new Student("003", "王五", "二班")); courses.Add(new Courses("001", "数学", 20)); courses.Add(new Courses("001", "语文", 20)); courses.Add(new Courses("001", "物理", 15)); courses.Add(new Courses("002", "历史", 20)); courses.Add(new Courses("002", "政治", 20)); courses.Add(new Courses("002", "语文", 30)); courses.Add(new Courses("003", "经济学", 20)); courses.Add(new Courses("003", "企业管理", 20)); courses.Add(new Courses("003", "财务管理", 30)); } } public class Student { public String Name { get; set; } public String Class { get; set; } public String ID { get; set; } public Student(String id,String name, String c) { ID = id; Name = name; Class = c; } public override string ToString() { return String.Format("学号:{0}\t姓名:{1}\t班级:{2}", this.ID, this.Name, this.Class); } } public class Courses { public String Name { get; set; } public int Credit { get; set; } public String StudentId { get; set; } public Courses(String id,String name, int credit) { StudentId = id; Name = name; Credit = credit; } public override string ToString() { return String.Format("课程名称:{0}\t学时:{1}", this.Name, this.Credit); } } }
整合:http://www.jb51.net/article/43343.htm
https://blog.csdn.net/yysyangyangyangshan/article/details/7349551
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
2015-12-14 JS与C#编码解码
2015-12-14 @Register指令
2015-12-14 asp.net中URL参数传值中文乱码的三种解决办法
2015-12-14 谷歌浏览器Chrome不再支持showModalDialog的解决办法