Using the OLE DB Provider
To start, create a new Windows Forms project named
SearchExample, add a button, a text box and a list box to the newly created form, and name them
btnExecuteQuery, txtInput and
lstResults respectively. After that, modify the form code to look like
Listing 1, which starts by defining a helper method named
ExecuteReader() that accepts a SQL query as an argument and returns the results in the form of an OleDbDataReader object. The
ExecuteReader() method first retrieves the OLE DB search provider connection string from the
app.config file.
string connectionString = System.Configuration.
ConfigurationManager.AppSettings["WDSConnectionString"];
That connection string is defined in the
<appSettings> section of the
app.config file as follows:
<appSettings>
<add key="WDSConnectionString"
value="Provider=Search.CollatorDSO;
Extended Properties='Application=Windows';"/>
</appSettings>
Because search operations are read-only, the search OLE DB provider supports only
SELECT statements.
Next,
ExecuteReader() creates an instance of the OleDbConnection object, passing the connection string to its constructor, then opens the connection using the
Open() method:
_connection = new OleDbConnection(connectionString);
_connection.Open();
After that it creates an instance of the OleDbCommand object, and sets its various properties to the appropriate values:
OleDbCommand command = new OleDbCommand();
command.Connection = _connection;
command.CommandText = query;
Finally, it executes the query by invoking the
OleDbCommand.ExecuteReader() method and returns the results back to the caller:
OleDbDataReader reader = command.ExecuteReader();
return reader;
As you can see from the
ExecuteReader() implementation, the ADO.NET code required to perform search is
exactly the same as executing a query against a data source. However if you look at the button-click code in
Listing 1, you'll see that the query passed as an input parameter to
ExecuteReader() differentiates this search query from a traditional SQL query.
I'll examine the search query format in depth. The button's
Click event concatenates the query:
private void btnExecuteQuery_Click(object sender, EventArgs e)
{
string query = string.Format(
"SELECT System.ItemNameDisplay, System.ItemType FROM " +
" systemindex WHERE CONTAINS(\"System.FileName\", " +
" '\"*{0}*\"')", txtInput.Text);
The preceding query searches the
System.FileName property for a match to the text entered by a user in the TextBox and return the values of the System.ItemNameDisplay and System.ItemType properties. The syntax of the query is as follows:
SELECT <Properties>
FROM [machineName.]SYSTEMINDEX
[WHERE <predicates>]
Here's a more detailed explanation of each of the query components.
- SELECT <Properties>Represents a list of one or more comma-separated properties defined in the Windows Vista property system. Note that the familiar SELECT * syntax is not supported, which means you must explicitly list the names of the properties you want to search. For a complete listing of the properties supported by Windows Vista, refer to the documentation. In this example, the "Core" category contains the properties you need. The documentation describes System.ItemNameDisplay as "the unique representation of the item name most appropriate for end users" and System.ItemType as "the canonical type of the item [...] intended to be programmatically parsed."
- FROM [machineName.]SYSTEMINDEXHere you specify "SYSTEMINDEX," which is the only local catalog you can query. However you also have the option of querying a remote catalog if the remote computer has the required software and configuration settings.
- WHERE <predicates>The WHERE clause supports the following predicates:
- Simple predicates: LIKE and literal value comparisons (<,>,=)
- Full-text predicates: CONTAINS and FREETEXT
- Search depth predicates: SCOPE and DIRECTORY
The example query uses the
CONTAINS predicate in the query to search for all the files where the filename contains a match to the input entered by the user.
Listing 1 supplies the completed query as an argument to the
ExecuteReader() helper method and assigns the results returned from the
ExecuteReader() method to a local variable:
OleDbDataReader reader = ExecuteReader(query);
lstResults.Items.Clear();
 | |
Figure 1. OLE DB Search Provider Output: Running the search fills the list box with the values of the System.ItemNameDisplay and System.ItemType properties. |
To display the data, you loop through the OleDbDataReader object and display the values of the first two columns:
while (reader.Read())
{
lstResults.Items.Add(reader.GetString(0)
+ ".........." +
reader.GetString(1).ToString());
}
Finally, close the OleDbDataReader object using the
Close() method:
reader.Close();
}
When you run the query, you'll see generated output that looks similar to
Figure 1.