LINQ to TerraServer Provider Sample
This sample is a custom LINQ provider for the TerraServer-USA Web service. It also contains a sample client application that uses the custom LINQ provider to query the Web service for geographical data.
The TerraServer-USA Web service exposes a method that returns
information about locations in the
A LINQ provider that implements the System.Linq.IQueryable<T> interface, such as this one, enables LINQ queries to be written against the data source that the provider connects to. A provider may execute the query functionality on the data itself, or it may translate the LINQ query into a query language that is appropriate for the data source that it connects to. This provider obtains raw data from the Web service and then modifies the original query in such a way that LINQ to Objects handles the query execution.
Security Note:
This sample code is intended to illustrate a concept, and it shows only the code that is relevant to that concept. It may not meet the security requirements for a specific environment, and it should not be used exactly as shown. We recommend that you add security and error-handling code to make your projects more secure and robust. Microsoft provides this sample code "AS IS" with no warranties.
Requirements
You need the following components to run this sample:
· Visual Studio 2008
To run the client application in Visual Studio
1. Open the file LinqToTerraServerProvider.sln with Visual Studio.
2. Press F5 to run the application.
File Descriptions
The following table lists the files in the LinqToTerraServerProvider project.
File |
Description |
Evaluator.cs |
Partially evaluates the query's expression tree. This translates all local variable references in the LINQ query into values. |
ExpressionTreeHelpers.cs |
Contains methods that can be used to determine information about and extract data from specific types of expression trees. |
ExpressionTreeModifier.cs |
An expression tree visitor subclass that modifies the expression tree that represents the complete LINQ query. |
ExpressionVisitor.cs |
The base expression tree visitor class. |
InnermostWhereFinder.cs |
An expression tree visitor subclass that finds the expression in the query's expression tree that represents the innermost call to the System.Linq.Queryable.Where method. This innermost expression is the expression that the provider extracts the search locations from. |
InvalidQueryException.cs |
Defines an exception that is thrown when an invalid query is submitted. |
LocationFinder.cs |
An expression tree visitor subclass that extracts location information from the LINQ query to use in the Web service request. This class understands location information that is provided in one of the following forms: ·
An equality expression, for example place.Name ==
" · A method call expression for the method System.String.StartsWith, for example place.Name.StartsWith("Seat"). · A method call expression for the method System.Linq.Enumerable.Contains<T> or System.Collections.Generic.List<T>.Contains, for example placeList.Contains(place.Name). |
Place.cs |
Defines a custom .NET type to represent the data from the Web service. |
QueryableTerraServerData.cs |
Contains the type the client query defines queries against. This type implements System.Linq.IOrderedQueryable<T> to support sort operations in the query. Because System.Linq.IOrderedQueryable<T> derives from System.Linq.IQueryable<T>, by implementing System.Linq.IOrderedQueryable<T> this type also implements System.Linq.IQueryable<T>. |
TerraServerQueryContext.cs |
Contains a class that organizes the work of executing a query. |
TerraServerQueryProvider.cs |
Contains the type that implements the System.Linq.IQueryProvider interface. The methods that this interface defines are called by the standard query operator methods that are defined in System.Linq.Queryable, to execute the query. |
TypeSystem.cs |
This helper class implements a method that is used to supply the element type of the generic collection that contains the query results. |
WebServiceHelper.cs |
Obtains data from the Web service. This code contains two checks that enhance the usability of the provider library. The first check limits the maximum time that a client application will wait for a response by limiting the total number of calls that are made to the Web service, per query, to five. The second check determines whether the number of results returned by the Web service is equal to the maximum number of results that it can return. If the number of results is the maximum number, it is likely that the results from the Web service are truncated. Instead of returning an incomplete list to the client, the provider throws an exception. |
The following table lists the files in the ClientApp project.
File |
Description |
Program.cs |
Contains three example LINQ queries that query the QueryableTerraServerData type defined in the LinqToTerraServerProvider project. |
app.config |
Contains an endpoint that defines how the application should communicate with the Web service. |
For a more detailed discussion of the design of this custom LINQ provider, see the topic titled Walkthrough: Creating an IQueryable LINQ Provider in the MSDN Library.