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 United States when the method is given part or all of a location name. This method, which is named GetPlaceList, is the method that the LINQ provider calls to obtain the data that the LINQ query is run against. The provider uses Windows Communication Foundation (WCF) to communicate with the Web service. For more information about the TerraServer-USA Web service, see Overview of the TerraServer-USA Web Services.

A LINQ provider that implements the System.Linq.IQueryable(Of 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 LinqToTerraServer.sln with Visual Studio.

2.      Right click on the LinqToTerraServer project node and click Rebuild.

3.      Right click on ClientApp project node and click Add Reference

4.      Click on the Projects tab in the dialog and select LinqToTerraServer and press Ok.

5.      Build entire solution

6.      Press F5 to run the application.

File Descriptions

The following table lists the files in the LinqToTerraServerProvider project.

 

File

Description

Evaluator.vb

Partially evaluates the query's expression tree. This translates all local variable references in the LINQ query into values.

ExpressionTreeHelpers.vb

Contains methods that can be used to determine information about and extract data from specific types of expression trees.

ExpressionTreeModifier.vb

An expression tree visitor subclass that modifies the expression tree that represents the complete LINQ query.

ExpressionVisitor.vb

The base expression tree visitor class.

InnermostWhereFinder.vb

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.vb

Defines an exception that is thrown when an invalid query is submitted.

LocationFinder.vb

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 = "Seattle".

·         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(Of T) or System.Collections.Generic.List(Of T).Contains, for example placeList.Contains(place.Name).

Place.vb

Defines a custom .NET type to represent the data from the Web service.

QueryableTerraServerData.vb

Contains the type the client query defines queries against. This type implements System.Linq.IOrderedQueryable(Of T) to support sort operations in the query. Because System.Linq.IOrderedQueryable(Of T) derives from System.Linq.IQueryable(Of T), by implementing System.Linq.IOrderedQueryable(Of T) this type also implements System.Linq.IQueryable(Of T).

TerraServerQueryContext.vb

Contains a class that organizes the work of executing a query.

TerraServerQueryProvider.vb

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.vb

This helper class implements a method that is used to supply the element type of the generic collection that contains the query results.

WebServiceHelper.vb

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

Module1.vb

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.