DataView 使用

DataView 直译是 数据视图。由数据库表(Table)映射到DataTable不难联想到 数据库视图 映射到 DataView。

 

数据库中视图是一个虚表,数据库中存储的只是一句查询SQL语句,每次程序访问此视图时,原理类似于执行此SQL语句,生成一个临时表,然后程序再对此临时表操作,结果对实表一样有效。

视图通常只是为了简化程序的查询操作,允许在一个实表上建立多个视图
同样的,DataView表示用于排序、筛选、搜索、编辑和导航的 DataTable 的可绑定数据的自定义视图。

 

举一个简单例子来说明它的作用。
有时候你想把DataTable的一部分数据绑定到控件1,而把DataTable的全部数据绑定到控件2,那么利用DataView可以简单地实现。

 

下面来看看DataView 的每个功能实现。

 

1、排序

    创建一个空页面Default.aspx,在页面中添加一个按钮和一个GridView控件

  1. <div>
  2.     <asp:Button ID="Button1" runat="server" Text="按id排序" OnClick="Button1_Click" />
  3.     <br />
  4.     <asp:GridView ID="GridView1" runat="server">
  5.     </asp:GridView>
  6. </div>

    在后台代码中,我们手动创建一个DataTable数据源,以下的操作都基于此数据源。如下

  1.     //创建数据源
  2.     private DataTable CreateTable()
  3.     {
  4.         DataTable dt = new DataTable();
  5.         dt.Columns.Add(new DataColumn("id"typeof(int)));
  6.         dt.Columns.Add(new DataColumn("name"typeof(string)));
  7.         int[] ids ={ 8, 5, 4, 3, 1, 9, 6, 7, 2 };
  8.         DataRow dr;
  9.         for (int i = 0; i < ids.Length; i++)
  10.         {
  11.             dr = dt.NewRow();
  12.             dr[0] = ids[i];
  13.             dr[1] = "not_" + ids[i].ToString();
  14.             dt.Rows.Add(dr);
  15.         }
  16.         return dt;
  17.     }

    在Page_Load中添加如下代码,初使化页面

  1.     protected void Page_Load(object sender, EventArgs e)
  2.     {
  3.         if (!IsPostBack)
  4.         {
  5.             if (ViewState["data"] == null)
  6.             {
  7.                 ViewState["data"] = CreateTable();
  8.             }
  9.             this.GridView1.DataSource = ViewState["data"as DataTable;
  10.             this.GridView1.DataBind();
  11.         }
  12.     }

对Button1的Click事件实现对ID列的排序

  1.     //排序
  2.     protected void Button1_Click(object sender, EventArgs e)
  3.     {
  4.         DataView dv;
  5.         if (ViewState["data"] != null)
  6.         {
  7.             dv = (ViewState["data"as DataTable).DefaultView;
  8.         }
  9.         else
  10.         {
  11.             dv = CreateTable().DefaultView;
  12.         }
  13.         //字符串不区分大小写
  14.         dv.Sort = "ID ASC";
  15.         this.GridView1.DataSource = dv;
  16.         this.GridView1.DataBind();
  17.     }

页面运行的初始状态如下

单击按钮后如下

 

可见排序的重点只是对 DataView.Sort 属性进行赋值 dv.Sort = "ID ASC";

2、筛选

    实现筛选主要是对DataView.RowFilter 属性操作。

    最简单的比如

    dv.RowFilter = "name > 'not_5'";

    但DataView.RowFilter 支持更为复杂的表达式,如

    dv.RowFilter = "id in (1,3,5,7)";

    dv.RowFilter = "name like 'not_5*'";

    更详细的可以参考 DataColumn.Expression 属性

    http://msdn.microsoft.com/zh-cn/library/system.data.datacolumn.expression.aspx

    

<think> 我们正在讨论的是C#中DataView使用方法。根据用户的问题,他想要获取DataView使用示例和方法。结合之前引用的内容,我们可以总结出DataView主要用于数据绑定、排序、过滤和分页等场景。下面我将提供一个完整的示例,展示DataView的常见用法。 ### 示例场景 假设我们有一个包含员工信息的DataTable,我们将使用DataView实现以下功能: 1. 数据绑定到控件(如DataGridView) 2. 数据排序 3. 数据过滤 4. 利用DataView进行分页 ### 完整代码示例 ```csharp using System; using System.Data; using System.Windows.Forms; public class DataViewDemo : Form { private DataGridView dataGridView; private Button btnSort; private Button btnFilter; private Button btnNextPage; private Button btnPrevPage; private Label lblPageInfo; private DataView dv; private int currentPage = 1; private int pageSize = 5; public DataViewDemo() { InitializeComponents(); LoadData(); } private void InitializeComponents() { dataGridView = new DataGridView { Dock = DockStyle.Top }; btnSort = new Button { Text = "按姓名排序", Top = 200 }; btnFilter = new Button { Text = "过滤部门=技术部", Top = 230 }; btnPrevPage = new Button { Text = "上一页", Top = 260 }; btnNextPage = new Button { Text = "下一页", Top = 260, Left = 80 }; lblPageInfo = new Label { Top = 300 }; btnSort.Click += BtnSort_Click; btnFilter.Click += BtnFilter_Click; btnPrevPage.Click += BtnPrevPage_Click; btnNextPage.Click += BtnNextPage_Click; Controls.AddRange(new Control[] { dataGridView, btnSort, btnFilter, btnPrevPage, btnNextPage, lblPageInfo }); } private void LoadData() { // 创建示例数据表 DataTable dt = new DataTable("Employees"); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Department", typeof(string)); dt.Columns.Add("Salary", typeof(decimal)); // 添加示例数据 dt.Rows.Add(1, "张三", "技术部", 8000); dt.Rows.Add(2, "李四", "市场部", 7500); dt.Rows.Add(3, "王五", "技术部", 9000); dt.Rows.Add(4, "赵六", "财务部", 8500); dt.Rows.Add(5, "钱七", "技术部", 9500); dt.Rows.Add(6, "孙八", "市场部", 7800); dt.Rows.Add(7, "周九", "技术部", 10000); dt.Rows.Add(8, "吴十", "财务部", 9200); // 创建DataView并绑定到DataGridView dv = new DataView(dt); BindDataView(); } private void BindDataView() { // 设置分页 dv.AllowPaging = true; // 注意:实际上DataView本身没有分页属性,我们通过RowFilter模拟分页 ApplyPaging(); dataGridView.DataSource = dv; UpdatePageInfo(); } private void ApplyPaging() { int startIndex = (currentPage - 1) * pageSize; dv.RowFilter = $"RowNumber >= {startIndex + 1} AND RowNumber <= {startIndex + pageSize}"; } private void UpdatePageInfo() { lblPageInfo.Text = $"第 {currentPage} 页 / 总 {Math.Ceiling(dv.Table.Rows.Count / (double)pageSize)} 页"; } // 排序按钮事件 private void BtnSort_Click(object sender, EventArgs e) { dv.Sort = "Name ASC"; // 按姓名升序排序 } // 过滤按钮事件 private void BtnFilter_Click(object sender, EventArgs e) { dv.RowFilter = "Department = '技术部'"; // 过滤出技术部员工 currentPage = 1; // 重置到第一页 ApplyPaging(); UpdatePageInfo(); } // 上一页按钮事件 private void BtnPrevPage_Click(object sender, EventArgs e) { if (currentPage > 1) { currentPage--; ApplyPaging(); UpdatePageInfo(); } } // 下一页按钮事件 private void BtnNextPage_Click(object sender, EventArgs e) { int totalPages = (int)Math.Ceiling(dv.Table.Rows.Count / (double)pageSize); if (currentPage < totalPages) { currentPage++; ApplyPaging(); UpdatePageInfo(); } } [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run(new DataViewDemo()); } } ``` ### 关键功能说明 1. **DataView基础用法** - 创建DataView:`DataView dv = new DataView(DataTable);` - 默认视图:`DataTable.DefaultView`获取默认视图 2. **数据绑定** ```csharp dataGridView.DataSource = dv; // 绑定到DataGridView ``` 3. **数据排序** ```csharp dv.Sort = "ColumnName ASC|DESC"; // 设置排序 ``` 4. **数据过滤** ```csharp dv.RowFilter = "条件表达式"; // 类似SQL的WHERE子句 ``` 示例: - 数值过滤:`"Salary > 8000"` - 文本过滤:`"Department = '技术部'"` - 日期过滤:`"BirthDate > #2020-01-01#"` 5. **分页实现** - 注意:DataView本身不直接支持分页,但可以通过RowFilter模拟实现 - 原理:计算当前页数据范围,设置RowFilter限制显示行数 ### 高级技巧 1. **多条件过滤** ```csharp dv.RowFilter = "Department = '技术部' AND Salary > 8000"; ``` 2. **动态排序** ```csharp // 根据用户选择动态排序 string sortColumn = "Name"; dv.Sort = sortColumn + " ASC"; ``` 3. **查找特定行** ```csharp DataRowView[] rows = dv.FindRows(123); // 查找主键为123的行 ``` 4. **绑定到下拉列表** ```csharp comboBox.DataSource = dv; comboBox.DisplayMember = "Name"; comboBox.ValueMember = "ID"; ``` 5. **去除重复值** ```csharp DataView distinctView = new DataView(table); distinctView.Sort = "Department"; // 先排序 comboBox.DataSource = distinctView.ToTable(true, "Department"); // 去重 ``` ### 注意事项 1. **性能考虑**:频繁修改RowFilter或Sort可能导致性能问题,尤其大数据量时 2. **线程安全**:DataView不是线程安全的,多线程环境需同步访问 3. **空值处理**:过滤条件中处理空值需用`IS NULL`或`IS NOT NULL` ```csharp dv.RowFilter = "Department IS NOT NULL"; ``` 通过合理使用DataView,可以大幅简化数据操作逻辑,提高程序效率[^1][^2][^4]。 §§相关问题§§ 1. DataView与LINQ to DataSet有什么区别? 2. 如何实现DataView的多列排序? 3. 在ASP.NET Core中如何使用DataView? 4. DataView的RowFilter语法有哪些高级用法? 以上示例和说明涵盖了DataView的主要使用方法,可以根据实际需求进行调整和扩展。 </think> 以下是C#中DataView的完整使用示例和方法详解,涵盖排序、过滤、分页和绑定等核心功能: ### 一、DataView基础使用 ```csharp // 创建DataTable DataTable dt = new DataTable("Employees"); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Department", typeof(string)); dt.Columns.Add("Salary", typeof(decimal)); // 添加数据 dt.Rows.Add(1, "张三", "技术部", 15000); dt.Rows.Add(2, "李四", "市场部", 12000); dt.Rows.Add(3, "王五", "技术部", 18000); dt.Rows.Add(4, "赵六", "财务部", 10000); // 创建DataView DataView dv = new DataView(dt); // 绑定到DataGridView dataGridView1.DataSource = dv; // [^1] ``` ### 二、数据排序 ```csharp // 单列排序 dv.Sort = "Salary DESC"; // 按薪资降序 // 多列排序 dv.Sort = "Department ASC, Salary DESC"; // 先按部门升序,再按薪资降序 // 动态排序 dv.Sort = "Name " + (isAscending ? "ASC" : "DESC"); ``` ### 三、数据过滤 ```csharp // 简单过滤 dv.RowFilter = "Department = '技术部'"; // [^2] // 复杂条件过滤 dv.RowFilter = "Salary > 12000 AND Department LIKE '%技术%'"; // 日期过滤 dv.RowFilter = $"HireDate > #{DateTime.Now.AddYears(-1):yyyy-MM-dd}#"; // 动态过滤 string dept = comboBox1.SelectedValue?.ToString(); dv.RowFilter = !string.IsNullOrEmpty(dept) ? $"Department = '{dept}'" : ""; ``` ### 四、数据分页 ```csharp // 分页设置 int pageSize = 5; int currentPage = 1; // 分页实现 public void BindPagedData() { DataView dv = new DataView(originalTable); dv.AllowPaging = true; // [^3] dv.PageSize = pageSize; dv.PageIndex = currentPage - 1; // 绑定到控件 dataGridView1.DataSource = dv; lblPageInfo.Text = $"第{currentPage}页/共{dv.PageCount}页"; } // 翻页按钮事件 private void btnNext_Click(object sender, EventArgs e) { if (currentPage < dv.PageCount) { currentPage++; BindPagedData(); } } ``` ### 五、高级绑定技巧 ```csharp // 绑定到ComboBox(去重) DataView distinctDepts = new DataView(dt); distinctDepts.Sort = "Department"; comboBox1.DataSource = distinctDepts.ToTable(true, "Department"); // [^4] comboBox1.DisplayMember = "Department"; // 主从表联动 DataRelation relation = new DataRelation("DeptEmp", dtDepartments.Columns["DeptID"], dtEmployees.Columns["DeptID"]); dataSet.Relations.Add(relation); // 获取部门下的员工 DataView deptEmployees = new DataView(dtEmployees); deptEmployees.RowFilter = $"DeptID = {selectedDeptId}"; // 数据汇总 decimal totalSalary = (decimal)dt.Compute("SUM(Salary)", "Department = '技术部'"); ``` ### 六、数据编辑与更新 ```csharp // 添加新行 DataRowView newRow = dv.AddNew(); newRow["Name"] = "新员工"; newRow["Department"] = "人事部"; newRow.EndEdit(); // 修改数据 dv[0]["Salary"] = 16000; dv[0].EndEdit(); // 删除行 dv.Delete(0); // 删除第一行 // 提交更改 dt.AcceptChanges(); ``` ### 七、性能优化技巧 1. **减少数据量**:过滤后再绑定 ```csharp DataView filtered = new DataView(dt, "Salary > 10000", "", DataViewRowState.CurrentRows); ``` 2. **禁用通知**:批量操作时提高性能 ```csharp dv.AllowEdit = false; // 执行批量操作 dv.AllowEdit = true; ``` 3. **使用索引**:频繁搜索时创建索引 ```csharp dv.Sort = "ID"; // 排序后自动创建索引 int index = dv.Find(1001); // 快速查找 ``` ### 八、实际应用场景 1. **动态查询面板**:用户选择不同条件实时过滤数据 2. **报表生成**:对数据进行分组、排序后导出 3. **数据验证**:通过RowFilter检查数据完整性 ```csharp DataView invalid = new DataView(dt, "Salary < 0 OR Salary > 100000", "", DataViewRowState.CurrentRows); if (invalid.Count > 0) { /* 处理异常数据 */ } ``` ### 注意事项 1. **线程安全**:DataView非线程安全,多线程环境需同步访问 2. **空值处理**:过滤条件中需处理NULL值 ```csharp dv.RowFilter = "Department IS NOT NULL"; ``` 3. **性能监控**:大数据量时注意分页和索引优化 以上示例覆盖了DataView的核心功能,通过合理使用可以显著简化数据处理逻辑[^1][^2][^3][^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值