C#中DataTable的LINQ查询:终极指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

通过LINQ操作DataTable:20分钟从新手到大师

\n\n

想象一下这个场景:您正在用C#编写一个应用程序,从数据库加载数据到DataTable中,然后……您需要根据复杂条件过滤行、按日期分组或合并两个表。老式的DataTable.Select("...")及其字符串过滤器在第二个条件时就失效了,而foreach循环则让代码变成一团意大利面。

\n\n

熟悉吗?那么欢迎来到DataTable的LINQ查询世界。这是您的超级工具,它将表格数据处理转变为优雅、可读且强大的代码。在本指南中,我们将涵盖所有内容:从基本的Where到高级的Join和GroupBy。我们开始吧!

\n\n
\n\n

什么是LINQ to DataSet,为什么需要它?

\n\n

LINQ(语言集成查询)是C#内置的查询语言。它的主要特点是:您可以使用熟悉的from、where、select运算符,以相同的方式对任何数据(数组、列表、XML、数据库)编写查询。

\n\n

但对于DataTable有一个细微差别:不能直接对其应用LINQ。DataTable没有实现IEnumerable<T>接口。解决方案是AsEnumerable()方法,它将表转换为DataRow对象的集合。LINQ正是与这个集合一起工作的。

\n\n

这种方法的优点:

\n
    \n
  • ✅ 类型安全:编译器能捕获列名中的错误
  • \n
  • ✅ 可读性:代码类似于SQL,但仍然是C#
  • \n
  • ✅ 强大:过滤、投影、分组、排序——一行代码搞定
  • \n
  • ✅ 性能:延迟执行(不加载多余数据)
  • \n
\n\n

让我们直接进入正题。在项目中添加对System.Data.DataSetExtensions的引用(通常已经存在)——然后开始吧。

\n\n
\n\n

数据准备:我们的测试表

\n\n

为了不空谈,我们创建一个包含产品数据的DataTable。下面的代码是我们所有示例的基础:

\n\n
// 1. 创建包含列的表\nDataTable products = new DataTable("Products");\nproducts.Columns.Add("Id", typeof(int));\nproducts.Columns.Add("Name", typeof(string));\nproducts.Columns.Add("Category", typeof(string));\nproducts.Columns.Add("Price", typeof(decimal));\nproducts.Columns.Add("DateAdded", typeof(DateTime));\n\n// 2. 添加行\nproducts.Rows.Add(1, "ASUS笔记本", "电子产品", 55000, DateTime.Now.AddDays(-10));\nproducts.Rows.Add(2, "罗技鼠标", "电子产品", 2500, DateTime.Now.AddDays(-5));\nproducts.Rows.Add(3, "《C#深度解析》", "书籍", 1800, DateTime.Now.AddDays(-2));\nproducts.Rows.Add(4, "索尼耳机", "电子产品", 12000, DateTime.Now.AddDays(-1));\nproducts.Rows.Add(5, "Moleskine笔记本", "文具", 1200, DateTime.Now.AddDays(-20));\nproducts.Rows.Add(6, "派克笔", "文具", 3500, DateTime.Now.AddDays(-15));\nproducts.Rows.Add(7, "戴尔显示器", "电子产品", 32000, DateTime.Now.AddDays(-30));
\n\n

现在我们有了7个产品。是时候应用LINQ的魔力了。

\n\n
\n\n

DataTable的基本LINQ查询

\n\n

1. 过滤(Where)——就像SQL WHERE

\n\n

假设我们需要选择所有价格超过10,000卢布的产品。没有LINQ,您需要编写一个循环来检查row["Price"]。使用LINQ,它看起来像这样:

\n\n
var expensiveProducts = products.AsEnumerable()\n    .Where(row => row.Field<decimal>("Price") > 10000);\n\nforeach (var row in expensiveProducts)\n{\n    Console.WriteLine($"{row["Name"]} - {row["Price"]} 卢布");\n}\n// 输出:ASUS笔记本 - 55000, 索尼耳机 - 12000, 戴尔显示器 - 32000
\n\n

重要提示:使用Field<T>("ColumnName")方法,而不是直接强制转换(decimal)row["Price"]。这样更安全:如果列是DBNull,Fie

博客

书籍推荐