Queries

A query is the primary object within the Query Application Access Block. A query represents a request for data from a data store or a request to store data in a data store. The goal behind the QAB is to separate the developer from concerns about the data store itself so that there is no requirement to know about the type of data store or the format of the data and the way it is stored. A query provides the consistent interface to all data store types and a DataSet is the common Data Transfer Object (DTO) between the Business Layer and the Data Access Layer.
A query may, of course, need a filter to refine the data that is returned or data to be stored away in a data set. Parameters are used in both of these cases. A full description is available from the Parameters page.
The QAB supports four different query types: Data Query, WCF Service Query, Web Service Query and XML Query plus the Custom Query for user extensions to other data store types like a proprietary format "flat file" for example.
The QueryFactory is used to create instances of query objects based on the query name:

[C#]
// create a query with a configured name of "Query Name"
IQuery query = QueryFactory.CreateQuery("Query Name");

Once you have a query object you can read or write to the configured data store with the ExecuteForRead() and ExecuteForWrite() methods. Both of these methods can take an optional IDictionary<string, object> set of parameters containing a set of parameter name and value pairs.
The ExecuteForRead() method always returns a DataSet even if it is empty:

[C#]
// create a query with a configured name of "Query With No Parameters"
IQuery query1 = QueryFactory.CreateQuery("Query With No Parameters");

// read data from the data store by calling the query's ExecuteForRead() method
DataSet returnedData1 = query1.ExecuteForRead();

// now create a query with a configured name of "Query With Parameters"
IQuery query2 = QueryFactory.CreateQuery("Query With Parameters");

// read data from the data store by calling the query's ExecuteForRead() method and passing in the set of parameter name value pairs
IDictionary<string, object> parameters = new IDictionary<string, object>();
parameters.Add("Id", 27);
parameters.Add("IsDeleted", "false");
DataSet returnedData2 = query2.ExecuteForRead(parameters);

The ExecuteForRead() method takes its data to be stored as an IDictionary<string, object> collection of parameter name value pairs:

[C#]
// create a query with a configured name of "Query For Update"
IQuery query = QueryFactory.CreateQuery("Query For Update");

// write data to the data store by calling the query's ExecuteForWrite() method and passing in the set of parameter name value pairs
IDictionary<string, object> parameters = new IDictionary<string, object>();
parameters.Add("Id", 27);
parameters.Add("Name", "Fred Bloggs");
parameters.Add("IsDeleted", "true");
query.ExecuteForWrite(parameters);

Of course if your DTO is the DataSet and you wish to write a modified DataSet away to a Data Store then you can use the overloaded ExecuteForWrite(DataSet) method:

[C#]
Dataset ds = GetDataSet(); // some method that returns a DataSet
// create a query with a configured name of "Query For Updating a DataSet"
IQuery query = QueryFactory.CreateQuery("Query For Updating a DataSet");
query.ExecuteForWrite(ds);

The query will trawl through the DataSet looking for table column names that match parameter names providing the matched column values to the query as parameters.

Data Queries

Data Queries target relational databases and because these queries interface to the DAAB can support any relational database that the DAAB can. This list is expanding and currently stands at: SQL Server, SQL Server CE, MS Access, Oracle, DB2, MySql, PostgreSQL and SQLite.
Data Queries convert to DBCommand objects through the DAAB and can run SQL query strings, call stored procedures (where supported) and even target tables directly (where supported). Parameters convert over to DBParameter objects.

WCF Service Queries

WCF Service queries target WCF services and convert to calls to service operations with parameters being passed as the parameters to these service operation calls. Note: that the QAB provides configuration to support WCF endpoints that specify a service address, a service binding (transport protocol) and a context.

Web Service Queries

Web Service queries are provided as a legacy support option for those who have not converted over to WCF Services and target Web services converting to calls to web method calls with parameters being passed as the parameters to these web method calls. Note that the QAB provides configuration to support the use of alternative service addresses from the one configured with the Service Reference.

XML Queries

XML file queries target XML fles and convert to LINQ to XML queries with parameters being used in those LINQ to XML queries. Note: that the QAB provides configuration to support XML namespaces for complex XML files. XML Queries assume a fairly basic XML layout with the configured data Element being immediately below the container element and searching based on Attributes and child Elements of that data "Element" as in this example where the data element is Basic3

[XML]
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="ReadBasic3.xslt"?>
<Basic3Collection>
  <Basic3 Id="e2e6a3bf-ca73-4c67-985b-f0b5ef1f7321">
    <Name>Test Basic3</Name>
    <OwnerId>f31038b6-499a-43d1-8423-47f1fd591755</OwnerId>
    <CreatedUserId>4c109191-c8d0-413a-90e5-d0a4b2acc352</CreatedUserId>
    <CreatedDate>2008-05-01T09:00:00</CreatedDate>
    <UpdatedUserId>816dae3c-9bbf-4c5f-9301-bc52575dcf09</UpdatedUserId>
    <UpdatedDate>2009-03-28T23:39:47.9089659+00:00</UpdatedDate>
    <IsPermanent>true</IsPermanent>
  </Basic3>
  <Basic3 Id="1F581C57-0187-4d2a-A861-958104968764">
    <Name>Another test</Name>
    <OwnerId>f31038b6-499a-43d1-8423-47f1fd591755</OwnerId>
    <CreatedUserId>4c109191-c8d0-413a-90e5-d0a4b2acc352</CreatedUserId>
    <CreatedDate>2008-05-02T09:30:00</CreatedDate>
    <UpdatedUserId>816dae3c-9bbf-4c5f-9301-bc52575dcf09</UpdatedUserId>
    <UpdatedDate>2009-03-28T23:39:47.9129659+00:00</UpdatedDate>
    <IsPermanent>false</IsPermanent>
  </Basic3>
  <Basic3 Id="DFA3C2D8-952E-4687-895C-33250283AC20">
    <Name>Call me</Name>
    <OwnerId>f31038b6-499a-43d1-8423-47f1fd591755</OwnerId>
    <CreatedUserId>4c109191-c8d0-413a-90e5-d0a4b2acc352</CreatedUserId>
    <CreatedDate>2008-05-03T10:00:00</CreatedDate>
    <IsPermanent>false</IsPermanent>
    <UpdatedUserId>816dae3c-9bbf-4c5f-9301-bc52575dcf09</UpdatedUserId>
    <UpdatedDate>2009-03-28T23:39:47.9159659+00:00</UpdatedDate>
  </Basic3>
</Basic3Collection>

For any searches that involve cross-element comparisons or values at deeper levels then a Custom Command is required.

Custom Queries

It is quite likely that a situation could arise where data is required from a data store that is not supported. Examples might include: the Windows Registry, The Active Directory, CSV flat files, Email messages, LDAP data stores etc. For this you can create a custom query by inheriting from QueryBase which in turn implements the IQuery interface. Through the Attributes property you will need a mechanism for linking a ParameterSet name. Within your code you can get a ParameterSet from its name with a call to ParameterSetFactory.CreateParameterSet("name"). For more details refer to the Extending the Query Application Block page.

Last edited Jun 15, 2010 at 8:22 PM by ewdev, version 5

Comments

clynnbob Oct 27, 2011 at 2:28 PM 
Are there any word real examples anywhere? I'm also having trouble finding the QueryFactory object in the libraries. They are used in your example above, but no object found.