从 DataTable 中获取数据、分组以及提取前五行的过程
在使用 LINQ 和 Lambda 表达式处理 DataTable
时,我们可以有效地对数据进行分组、筛选以及限制结果的数量。下面是一个具体的示例,演示如何实现这一过程。
1. 获取 DataTable
假设我们已经有一个 DataTable
,命名为 dt
,其中包含了一些员工数据,包括部门编号(DeptID
)等字段。
下面是基于 SQL Server 的创建部门表和员工表的 SQL 语句,并通过 DeptID
字段进行关联。
创建部门表(Department Table)
CREATE TABLE Department (
DeptID VARCHAR(10) PRIMARY KEY, -- 部门编号,主键
DeptName NVARCHAR(50) NOT NULL, -- 部门名称
Manager NVARCHAR(50), -- 部门负责人
DeptPhone NVARCHAR(15) -- 部门电话
);
创建员工表(Employee Table)
CREATE TABLE Employee (
EmployeeID INT PRIMARY KEY IDENTITY(1,1), -- 员工ID,主键,自增
Name NVARCHAR(50) NOT NULL, -- 员工姓名
Gender NVARCHAR(10), -- 性别
Age INT NOT NULL, -- 年龄
DeptID VARCHAR(10), -- 部门编号,外键
Position NVARCHAR(50), -- 职位
Contact NVARCHAR(15), -- 联系方式
FOREIGN KEY (DeptID) REFERENCES Department(DeptID) -- 外键约束,关联部门表
);
在部门表中插入三条数据
INSERT INTO Department (DeptID, DeptName, Manager, DeptPhone)
VALUES
('001', '人力资源部', '王经理', '010-12345678'),
('002', '财务部', '李经理', '010-87654321'),
('003', '市场部', '张经理', '010-11223344');
插入员工数据
-- 人力资源部的6条数据
INSERT INTO Employee (Name, Gender, Age, DeptID, Position, Contact)
VALUES
('王芳', '女', 25, '001', '助理', '13900000001'),
('李强', '男', 26, '001', '专员', '13900000002'),
('赵丽', '女', 28, '001', '主管', '13900000003'),
('张伟', '男', 27, '001', '经理助理', '13900000004'),
('杨静', '女', 24, '001', 'HR', '13900000005'),
('刘洋', '男', 29, '001', '招聘专员', '13900000006');
-- 财务部的6条数据
INSERT INTO Employee (Name, Gender, Age, DeptID, Position, Contact)
VALUES
('张红', '女', 30, '002', '助理', '13900000007'),
('李雪', '女', 26, '002', '专员', '13900000008'),
('周明', '男', 32, '002', '会计', '13900000009'),
('王刚', '男', 35, '002', '审计', '13900000010'),
('李华', '男', 28, '002', '财务助理', '13900000011'),
('陈琳', '女', 27, '002', '税务专员', '13900000012');
-- 市场部的6条数据
INSERT INTO Employee (Name, Gender, Age, DeptID, Position, Contact)
VALUES
('马婷', '女', 23, '003', '市场助理', '13900000013'),
('杨杰', '男', 29, '003', '市场专员', '13900000014'),
('张鹏', '男', 31, '003', '市场主管', '13900000015'),
('王欣', '女', 25, '003', '营销专员', '13900000016'),
('赵军', '男', 33, '003', '策划专员', '13900000017'),
('李娜', '女', 26, '003', '品牌推广', '13900000018');
2. 根据字段分组
我们可以使用 LINQ 的 GroupBy
方法对 DataTable
中的数据进行分组。在这个例子中,我们将根据 DeptID
字段进行分组:
Dim groups = dt.AsEnumerable().GroupBy(Function(emp) emp.Field(Of String)("DeptID"))
这行代码将 dt
中的所有行根据 DeptID
进行分组,并将结果存储在 groups
变量中。每个分组都是一个 IGrouping(Of String, DataRow)
类型,其中 Key
是部门编号,值是对应的 DataRow
集合。
3. 通过 Key 获取某一组
接下来,我们可以通过指定的部门编号(在这个例子中为 "003"
)来获取该组的数据:
Dim group = groups.Where(Function(g) g.Key = "003").FirstOrDefault()
这行代码将返回 Key
为 "003"
的分组。如果该组存在,group
将包含对应的 DataRow
集合;如果不存在,group
将为 Nothing
。
4. 只获取前五行
一旦获取到特定的分组,我们可以使用 Take
方法来限制结果,只获取前五行数据:
Dim topFiveRows = group.Take(5)
此行代码从 group
中提取出前五行。如果 group
中的行数少于五行,则返回所有行。
5. 示例代码总结
综合上述步骤,完整的代码如下:
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
Try
Dim sb4 = GetSearchSql4()
Dim parameters3 As New List(Of SqlParameter)
GetSearchPatameter(parameters3)
Dim dt As DataTable = db.ExecuteQuery(sb4.ToString)
'1.使用单个字段分组 使用 DeptID进行分组
Dim groups = dt.AsEnumerable().GroupBy(Function(emp) emp.Field(Of String)("DeptID"))
'根据Key进行筛选 从分组后的数据里,筛选Key="003" (也就是DeptID="003"的数据)
Dim group = groups.Where(Function(g) g.Key = "003").FirstOrDefault()
If group IsNot Nothing Then
'获取key的值
Dim keyOne = group.Key
'获取前五行
Dim topFiveRows = group.Take(5)
End If
'2. 使用多个字段分组 使用 DeptID,DeptName 和进行分组
Dim groups2 = dt.AsEnumerable().GroupBy(Function(emp) New With {
Key .DeptID = emp.Field(Of String)("DeptID"),
Key .DeptName = emp.Field(Of String)("DeptName")
})
'根据Key进行筛选
'从分组后的数据里,筛选Key.DeptID = "003" (DeptID="003") Key.DeptName = "市场部" (DeptName="市场部")
Dim group2 = groups2.Where(Function(g) g.Key.DeptID = "003" AndAlso g.Key.DeptName = "市场部").FirstOrDefault()
If group2 IsNot Nothing Then
'获取key的值 多个key
Dim groupKey1 = group2.Key.DeptID
Dim groupKey2 = group2.Key.DeptName
'获取前五行
Dim topFiveRows2 = groups2.Take(5)
End If
Catch ex As Exception
MessageBox.Show(ex, "错误")
Finally
'xxxxx
End Try
总结
通过以上步骤,我们展示了如何使用 LINQ 和 Lambda 表达式对 DataTable
进行分组、筛选和提取数据。这种方法不仅简洁明了,还能有效提高数据处理的效率。