65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 LINQ (C#) 在 Winforms 中创建数据的主从表示

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (18投票s)

2008 年 12 月 7 日

CPOL

3分钟阅读

viewsIcon

66157

downloadIcon

1763

使用 LINQ (C#) 在 Winforms 中创建数据的主从表示

引言

在构建企业应用程序时,我们可能需要开发主从事务展示或录入数据表单。

我想在我的 Windows 应用程序中使用 LINQ 的强大功能。本文通过一个简单的例子,展示了如何使用 C# Winforms 和 LINQ 实现主从数据展示。

背景

在我之前的文章中,我使用 Northwind 数据库来处理 LINQ,这里我使用自定义对象来保存数据。 LINQ 用于通过连接和分组从对象源提取数据。

在这个例子中,使用了两个类 Department(部门)和 Employee(员工),并在每个类中声明了必需的公共属性。 每个类都有构造函数来保存数据。

还使用了两个 GridView 来显示 Department 和 Employee 记录。 数据将通过 BindingSource 绑定到 GridView。

BindingSource 类 (System.Windows.Forms)

BindingSource 组件有多种用途。 首先,它通过提供货币管理、更改通知以及 Windows Forms 控件和数据源之间的其他服务,简化了窗体上控件与数据的绑定。 这是通过使用 DataSource 属性将 BindingSource 组件附加到您的数据源来实现的。

最初,数据将被加载到 BindingSource,然后 BindingSource 用于将数据放入 GridView 控件中。

在这种情况下,BindingSource 和 GridView 控件的 DataSource 属性都需要设置。

LINQ 数据将绑定到 Binding Source 的 DataSource 属性,而 BindingSource 用于设置 GridView 的 DataSource 属性。

为两个数据源创建对象列表并添加数据。

private List<Department> Departments = new List<Department>();
private List<Employee> Employees = new List<Employee>(); 

通过列表向 Department 添加数据。

Departments.Add(new Department(10, "Sales", "Hyderabad")); 

通过列表向 Employee 添加数据。

Employees.Add(new Employee(1, "Krishna Prasad", 10, "Manager", 30000)); 

将 GridView 的 AutoGeneratedColumns 属性设置为 true,以显示来自对象源的 BindingSource 数据。

dgvEmployees.AutoGenerateColumns = true;
dgvDepartments.AutoGenerateColumns = true;

可以像下面指定的那样对数据进行分组并从对象源检索。

var matchingEmployees = from dept in Departments
join emp in Employees on dept.DeptNo equals emp.DeptNo
into AvailableEmployees
select new { department = dept, employees = AvailableEmployees }; 

Dictionary 对象用于保存选定的分组数据。

词典

表示键和值的集合。

Dictionary<(Of <(TKey, TValue>)>) 泛型类提供了从一组键到一组值的映射。 字典的每个添加项都包含一个值及其关联的键。 通过使用其键检索值非常快,接近 O(1),因为 Dictionary<(Of <(TKey, TValue>)>) 类是作为哈希表实现的。

Dictionary 对象需要两个参数,第一个是键,第二个是值。

在这个例子中,Key 是 Department(记录),value 是所选 Department 的相关 Employee 记录。

private Dictionary<Department, IEnumerable<Employee>> GroupEmployee;

this.GroupEmployee = matchingEmployees.ToDictionary(x => x.department, y => y.employees);

现在数据已保存到 Dictionary 对象中。 每当在 master GridView 中更改 Master 记录(例如:此示例中的 Department)的选择时,需要在详细信息 GridView 中显示记录(例如:此示例中的 Employee 记录)。

可以通过 BindingSources 的 CurrentChanged 事件来实现此过程,因为它们绑定到特定数据,并且 GridView 绑定到 BindingSources。

private void bsDepartments_CurrentChanged(object sender, EventArgs e)
{
bsEmployees.DataSource = this.GroupEmployee [(Department) bsDepartments.Current];
} 

使用代码

下载附加的 Zip 文件,重新构建解决方案并运行 SecondLINQ 示例即可。

完整代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SecondLINQ
{
public partial class Form1 : Form
{
private List<Department> Departments = new List<Department>();
private List<Employee> Employees = new List<Employee>();
private Dictionary<Department, IEnumerable<Employee>> GroupEmployee;
public Form1()
{
InitializeComponent();
dgvEmployees.AutoGenerateColumns = true;
dgvDepartments.AutoGenerateColumns = true;
loadDepartments();
loadEmployees();
var matchingEmployees = from dept in Departments
join emp in Employees on dept.DeptNo equals emp.DeptNo
into AvailableEmployees select new { department = dept, employees = AvailableEmployees }; 

this.GroupEmployee = matchingEmployees.ToDictionary(x => x.department, y => y.employees);
bsDepartments.DataSource = GroupEmployee.Keys;
}
public class Department
{
private int deptNo = 0;
private String deptName = String.Empty;
private String deptLoc = String.Empty;
public Department() { }
public Department(int DeptNo, String DeptName, String DeptLoc)
{
deptNo = DeptNo;
deptName = DeptName;
deptLoc = DeptLoc;
}
public int DeptNo
{
set { deptNo = value; }
get {return deptNo;}
}
public String DeptName
{
set { deptName = value; }
get { return deptName; }
}
public String DeptLoc
{
set { deptLoc = value; }
get { return deptLoc; }
}
}
private class Employee
{
private int employeeNo;
private String employeeName;
private int deptNo;
private String job;
private Double salary;
public Employee() { }
public Employee(int EmployeeNo, String EmployeeName, int DeptNo, String Job, Double Salary)
{
employeeNo = EmployeeNo;
employeeName = EmployeeName;
deptNo = DeptNo;
job = Job;
salary = Salary;
}
public int EmployeeNo
{
set { employeeNo = value; }
get { return employeeNo; }
}
public String EmployeeName
{
set { employeeName = value; }
get { return employeeName; }
}
public int DeptNo
{
set { deptNo = value; }
get { return deptNo; }
}
public String Job
{
set { job = value; }
get { return job; }
}
public Double Salary
{
set { salary = value; }
get { return salary; }
}
}

private void loadDepartments()
{
Departments.Add(new Department(10, "Sales", "Hyderabad"));
Departments.Add(new Department(20, "Purchases", "Mumbai"));
Departments.Add(new Department(30, "Admin", "Mumbai"));
Departments.Add(new Department(40, "Accounts", "Mumbai"));
Departments.Add(new Department(50, "Training", "Hyderabad"));
Departments.Add(new Department(60, "Stores", "Hyderabad"));
}

private void loadEmployees()
{
Employees.Add(new Employee(1, "Krishna Prasad", 10, "Manager", 30000));
Employees.Add(new Employee(2, "Rajesh", 10, "Clerk", 10000));
Employees.Add(new Employee(3, "Ramesh", 10, "Assistant", 5000));
Employees.Add(new Employee(4, "Ragesh", 10, "Computer Operator", 4000));
Employees.Add(new Employee(5, "Murali", 20, "Manager", 30000));
Employees.Add(new Employee(6, "Anil", 20, "Clerk", 10000));
Employees.Add(new Employee(7, "Karthik", 30, "Manager", 30000));
Employees.Add(new Employee(8, "Anirudh", 30, "Assistant", 7000));
Employees.Add(new Employee(9, "Sarma Chada", 40, "Manager", 15000));
Employees.Add(new Employee(10, "Anupama", 40, "Assistant", 3000));
Employees.Add(new Employee(10, "Anirudh", 40, "Accountant", 7000));
Employees.Add(new Employee(11, "Sailesh", 60, "Store Keeper", 4000));
}

private void bsDepartments_CurrentChanged(object sender, EventArgs e)
{
bsEmployees.DataSource = this.GroupEmployee [(Department) bsDepartments.Current];
}
}
}

关注点

通过 LINQ 连接和分组数据非常容易。 我们可以编写一个简单的 LINQ 表达式(使用 Lambda)来从多个表获取复杂数据。

历史

发布和更新于 2008 年 11 月 7 日

© . All rights reserved.