在 LINQ to DataSet 上下文中创建 DataView 有两种方式。 您可以通过针对 DataTable 的 LINQ to DataSet 查询创建 DataView,也可以从类型化或非类型化 DataTable 创建该对象。 在这两种情况下,您可以通过使用 AsDataView 扩展方法之一来创建 DataView;DataView 不能直接在 LINQ to DataSet 上下文中构造。
创建 DataView 之后,您可以将其绑定到 Windows 窗体应用程序或 ASP.NET 应用程序中的 UI 控件上,或者更改筛选和排序设置。
DataView 构造一个索引,该索引可显著提高可使用该索引的操作(如筛选和排序)的性能。 创建 DataView 及修改任何排序或筛选信息时,均会生成 DataView 的索引。 创建 DataView 然后设置排序或筛选信息会使索引生成至少两次:一次是在创建 DataView 时,另一次是在修改任何排序或筛选属性时。
有关使用 DataView 进行筛选和排序的更多信息,请参见使用 DataView 进行筛选 (LINQ to DataSet)和使用 DataView 进行排序 (LINQ to DataSet)。
通过 LINQ to DataSet 查询创建 DataView
可以通过 LINQ to DataSet 查询结果创建 DataView 对象,查询结果是 DataRow 对象的投影。 新创建的 DataView 会从创建它的查询继承筛选和排序信息。
![]() |
---|
在大多数情况下,用于筛选和排序的表达式不应有副作用且必须是确定的。另外,表达式不应包含依赖于固定执行次数的任何逻辑,因为排序和筛选操作可能会执行任意次。 |
不支持通过返回匿名类型的查询或执行联接操作的查询创建 DataView。
在用于创建 DataView 的查询中仅支持以下查询运算符:
请注意,当从 LINQ to DataSet 查询创建 DataView 时,Select<TRow, S> 方法必须是查询中调用的最后的方法。如下面的示例所示,此示例创建了按照欠款总额排序的联机订单的 DataView:
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
Order By order.Field(Of Decimal)("TotalDue") _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
orderby order.Field<decimal>("TotalDue")
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
也可以在从查询创建 DataView 后,使用基于字符串的 RowFilter 和 Sort 属性对其进行筛选和排序。 请注意,这将清除继承自查询的排序和筛选信息。 下面的示例通过按以“S”开头的姓氏进行筛选的 LINQ to DataSet 查询创建 DataView。 将基于字符串的 Sort 属性设置为先按姓氏升序排序,然后按名字降序排序:
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName").StartsWith("S") _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
view.Sort = "LastName desc, FirstName asc"
DataTable contacts = dataSet.Tables["Contact"];
EnumerableRowCollection<DataRow> query = from contact in contacts.AsEnumerable()
where contact.Field<string>("LastName").StartsWith("S")
select contact;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
view.Sort = "LastName desc, FirstName asc";
从数据表创建 DataView
除了通过 LINQ to DataSet 查询创建 DataView 对象外,还可以通过使用 AsDataView 方法从 DataTable 创建该对象。
下面的示例从 SalesOrderDetail 表创建 DataView 并将其设置为 BindingSource 对象的数据源。 此对象充当 DataGridView 控件的代理。
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim view As DataView = orders.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
DataTable orders = dataSet.Tables["SalesOrderDetail"];
DataView view = orders.AsDataView();
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
在从 DataView 创建 DataTable 后,可以在其上设置筛选和排序。 下面的示例从 Contact 表创建 DataView 并将 Sort 属性设置为先按姓氏升序排序,然后按名字降序排序:
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.Sort = "LastName desc, FirstName asc"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
DataTable contacts = dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.Sort = "LastName desc, FirstName asc";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
不过,在通过查询创建 DataView 之后,设置 RowFilter 或 Sort 属性会带来性能降低,因为 DataView 将会构造一个索引来支持筛选和排序操作。 设置 RowFilter 或 Sort 属性会重新生成数据的索引,从而增加应用程序的系统开销并降低性能。 在可能的情况下,最好在第一次创建 DataView 时指定筛选和排序信息并避免之后对其进行修改。