DataViews
This document provides a comprehensive overview of DataViews within ADO.NET, explaining their purpose, functionality, and usage for manipulating and presenting data.
Introduction to DataViews
A DataView
object provides a way to create a custom view of the data contained within a DataTable
. It allows you to filter, sort, and navigate the rows of a DataTable
without actually modifying the underlying data itself. This is particularly useful when you need to display data in different ways for various UI controls, such as grids or dropdown lists.
Key features of DataView
include:
- Row Filtering: Select specific rows based on criteria.
- Row Sorting: Order rows based on one or more columns.
- Data Navigation: Move through the rows in the view.
- Real-time Updates: Automatically reflects changes made to the underlying
DataTable
.
DataView
objects are integral to data-bound controls in Windows Forms and ASP.NET, simplifying the process of presenting dynamic datasets.
Creating a DataView
To create a DataView
, you first need a DataTable
. You can then instantiate a DataView
by passing the DataTable
to its constructor. Optionally, you can specify initial filter and sort expressions.
C# Example: Basic DataView Creation
using System;
using System.Data;
public class DataViewExample
{
public static void Main(string[] args)
{
// 1. Create a DataTable
DataTable productsTable = new DataTable("Products");
productsTable.Columns.Add("ProductID", typeof(int));
productsTable.Columns.Add("ProductName", typeof(string));
productsTable.Columns.Add("Category", typeof(string));
productsTable.Columns.Add("Price", typeof(decimal));
// Add some sample data
productsTable.Rows.Add(1, "Laptop", "Electronics", 1200.00m);
productsTable.Rows.Add(2, "Keyboard", "Electronics", 75.50m);
productsTable.Rows.Add(3, "Desk Chair", "Furniture", 150.75m);
productsTable.Rows.Add(4, "Monitor", "Electronics", 300.00m);
productsTable.Rows.Add(5, "Office Desk", "Furniture", 450.00m);
// 2. Create a DataView from the DataTable
DataView productView = new DataView(productsTable);
Console.WriteLine($"Initial number of rows in DataView: {productView.Count}");
// You can now access data through productView
foreach (DataRowView row in productView)
{
Console.WriteLine($"{row["ProductName"]} - {row["Category"]}");
}
}
}
The DataView
can be initialized with filter and sort expressions:
C# Example: Initializing with Filter and Sort
// Create a DataView for electronics, sorted by price ascending
DataView electronicsView = new DataView(productsTable,
"Category = 'Electronics'",
"Price ASC",
DataViewRowState.CurrentRows);
Console.WriteLine("\nElectronics sorted by price:");
foreach (DataRowView row in electronicsView)
{
Console.WriteLine($"{row["ProductName"]} - ${row["Price"]}");
}
Filtering and Sorting
The primary power of DataView
lies in its ability to dynamically filter and sort data. These operations are performed using string expressions that resemble SQL WHERE and ORDER BY clauses.
Filtering
The RowFilter
property is used to specify a filter expression. Only rows that match the criteria will be included in the view.
C# Example: Applying a Filter
// Filter for products with a price greater than $200
productView.RowFilter = "Price > 200";
Console.WriteLine($"\nNumber of products with Price > 200: {productView.Count}");
foreach (DataRowView row in productView)
{
Console.WriteLine($"{row["ProductName"]} - ${row["Price"]}");
}
// Reset the filter
productView.RowFilter = "";
Sorting
The SortProperty
property is used to specify a sort expression. You can sort by one or more columns, in ascending (ASC) or descending (DESC) order.
C# Example: Applying Sorting
// Sort by Category, then by ProductName
productView.Sort = "Category ASC, ProductName ASC";
Console.WriteLine("\nAll products sorted by Category and Name:");
foreach (DataRowView row in productView)
{
Console.WriteLine($"{row["Category"]} - {row["ProductName"]}");
}
// Sort by Price descending
productView.Sort = "Price DESC";
Console.WriteLine("\nAll products sorted by Price (Descending):");
foreach (DataRowView row in productView)
{
Console.WriteLine($"{row["ProductName"]} - ${row["Price"]}");
}
// Reset the sort
productView.Sort = "";
Using DataViewManager
The DataViewManager
class is useful when you have a DataSet
containing multiple related DataTable
objects. It provides a default DataView
for each table in the DataSet
and manages them.
When you create a DataView
using a DataViewManager
, it can automatically apply default filter and sort settings based on relations defined within the DataSet
.
C# Example: Using DataViewManager
// Assume 'myDataSet' is a DataSet containing multiple DataTables
// Create a DataSet (for demonstration purposes)
DataSet myDataSet = new DataSet();
DataTable customersTable = new DataTable("Customers");
customersTable.Columns.Add("CustomerID", typeof(int));
customersTable.Columns.Add("Name", typeof(string));
customersTable.Rows.Add(101, "Alice Smith");
customersTable.Rows.Add(102, "Bob Johnson");
myDataSet.Tables.Add(customersTable);
DataTable ordersTable = new DataTable("Orders");
ordersTable.Columns.Add("OrderID", typeof(int));
ordersTable.Columns.Add("CustomerID", typeof(int));
ordersTable.Columns.Add("OrderDate", typeof(DateTime));
ordersTable.Rows.Add(1001, 101, new DateTime(2023, 10, 26));
ordersTable.Rows.Add(1002, 101, new DateTime(2023, 11, 15));
ordersTable.Rows.Add(1003, 102, new DateTime(2023, 10, 30));
myDataSet.Tables.Add(ordersTable);
// Create a DataViewManager
DataViewManager dvManager = new DataViewManager(myDataSet);
// Get a DataView for the Customers table
DataView customerView = dvManager.CreateDataView(myDataSet.Tables["Customers"]);
Console.WriteLine($"\nCustomers from DataViewManager:");
foreach (DataRowView row in customerView)
{
Console.WriteLine($"{row["Name"]}");
}
// Get a DataView for the Orders table
DataView orderView = dvManager.CreateDataView(myDataSet.Tables["Orders"]);
Console.WriteLine($"\nOrders from DataViewManager:");
foreach (DataRowView row in orderView)
{
Console.WriteLine($"Order ID: {row["OrderID"]}, Customer ID: {row["CustomerID"]}");
}
Advanced Scenarios
DataView Row States
DataView
can display different states of rows from the underlying DataTable
, such as:
DataViewRowState.CurrentRows
: Only currently visible rows.DataViewRowState.Added
: Rows that have been added but not yet accepted changes.DataViewRowState.Deleted
: Rows marked for deletion.DataViewRowState.ModifiedCurrent
: Rows that have been modified and are currently visible.DataViewRowState.ModifiedOriginal
: The original version of rows that have been modified.DataViewRowState.OriginalRows
: All original rows (before any changes).
You can specify which row states to include in your DataView
when filtering or sorting.
C# Example: Filtering Deleted Rows
// Assume productsTable has some deleted rows
// For example:
// productsTable.Rows[0].Delete();
// productsTable.AcceptChanges(); // This would remove them permanently.
// If not accepted, they exist in OriginalRows and ModifiedOriginal states.
// To see rows that were deleted and are still in the system before AcceptChanges
// DataView deletedRowsView = new DataView(productsTable,
// "",
// "",
// DataViewRowState.Deleted);
// Console.WriteLine($"\nNumber of deleted rows: {deletedRowsView.Count}");
// Note: Accessing data from deleted rows requires accessing the 'OldValues' property of DataRowView.
Using DataView with Data Binding
DataView
is commonly used as a data source for UI controls. When a DataView
is assigned to the DataSource
property of a data-bound control (like a DataGridView
in WinForms or a GridView in ASP.NET), the control automatically displays the data according to the DataView
's current filter and sort settings.
Best Practices
- Clear Filters and Sorts: When no longer needed, reset
RowFilter
andSort
properties to an empty string to improve performance and avoid unexpected behavior. - Use Efficient Expressions: Write filter and sort expressions that are as specific as possible to limit the data processed.
- Handle DataViewRowState: Be mindful of the
DataViewRowState
you are querying, especially when dealing with data that has been modified or deleted. DataViewManager
for Datasets: UtilizeDataViewManager
when working withDataSet
objects to easily manage views for multiple tables.- Avoid Redundant Views: If you only need one specific view of a
DataTable
, create a singleDataView
with appropriate filter and sort. If multiple views are needed, consider creating multipleDataView
instances.