建立 DataView 物件 (LINQ to DataSet)
目前有兩種方式可以在 LINQ to DataSet 內容中建立 DataView。 您可以透過 DataTable 從 LINQ to DataSet 查詢建立 DataView,也可以從具型別或不具型別的 DataTable 建立。 在這兩種情況中,您可以使用其中一個 AsDataView 擴充方法來建立 DataView;但無法在 LINQ to DataSet 內容中直接建構 DataView。
在您已經建立 DataView 之後,就可以將它繫結程序至 Windows Forms 應用程式或 ASP.NET 應用程式中的 UI 控制項,也可以變更篩選和排序設定。
DataView 會建構索引,以便大幅增加可使用索引之作業的效能,例如篩選和排序。 在您建立 DataView 以及修改任何排序或篩選資訊時,系統就會建立 DataView 的索引。 如果您建立 DataView,然後設定排序或篩選資訊,將會導致系統至少建立索引兩次:一次是建立 DataView 時,另一次是修改任何排序或篩選屬性時。
如需深入了解如何透過 DataView 進行篩選與排序,請參閱透過 DataView 進行篩選及透過 DataView 進行排序。
從 LINQ to DataSet 查詢中建立 DataView
您可以從 LINQ to DataSet 查詢的結果建立 DataView 物件,這些結果是 DataRow 物件的投影。 新建立的 DataView 會從建立此物件的查詢中繼承篩選和排序資訊。
注意
在大部分清況中,用於篩選和排序的運算式不應該具有副作用 (Side Effect) 而且必須具決定性。 此外,這些運算式不應該包含取決於固定執行次數的任何邏輯,因為排序和篩選作業可能會執行任何次數。
目前不支援從傳回匿名型別的查詢或執行聯結 (Join) 作業的查詢中建立 DataView。
在用來建立 DataView 的查詢中只支援使用下列查詢運算子:
請注意,從 LINQ to DataSet 查詢建立 DataView 時,Select 方法必須是查詢中呼叫的最終方法。 如以下範例所示,這會建立線上訂單的 DataView (依整體到期日排序):
DataTable orders = _dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag")
orderby order.Field<decimal>("TotalDue")
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
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
從查詢建立之後,也可以使用以字串為基礎的 RowFilter 和 Sort 屬性來排序和篩選 DataView。 請注意,這樣做會清除繼承自查詢的排序和篩選資訊。 下列範例會從依據以 'S' 為開頭之姓氏篩選的 LINQ to DataSet 查詢建立 DataView。 以字串為基礎的 Sort 屬性會設定為按照遞增順序排序姓氏,然後再按照遞減順序排序名字:
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";
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 中建立 DataView
除了從 LINQ to DataSet 查詢建立 DataView 物件以外,您也可以使用 AsDataView 方法從 DataTable 建立。
下列範例會從 SalesOrderDetail 資料表中建立 DataView,然後將它設定為 BindingSource 物件的資料來源。 這個物件會當做 DataGridView 控制項的 Proxy。
DataTable orders = _dataSet.Tables["SalesOrderDetail"];
DataView view = orders.AsDataView();
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim view As DataView = orders.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
在您已經從 DataView 中建立 DataTable 之後,就可以針對它設定篩選和排序。 下列範例會從 Contact 資料表中建立 DataView 並將 Sort 屬性設定為按照遞增順序排序姓氏,然後再按照遞減順序排序名字:
DataTable contacts = _dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.Sort = "LastName desc, FirstName asc";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.Sort = "LastName desc, FirstName asc"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
不過,在您已經從查詢中建立 RowFilter 之後設定 Sort 或 DataView 屬性會發生效能降低的情況,因為 DataView 會建構索引來支援篩選和排序作業。 設定 RowFilter 或 Sort 屬性會重建資料索引,因而增加應用程式的負荷並降低效能。 如果可能的話,最好是在您首次建立 DataView 時指定篩選和排序資訊,並且避免之後修改這項資訊。