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 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 data from the Web service and then modifies the original query in such a way that LINQ to Objects handles the query execution.

Security noteSecurity 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.

To get samples and instructions for installing them

  • Do one or more of the following:

    • On the Help menu, click Samples.

      The Readme displays information about samples.

    • Visit the Visual Studio 2008 Samples Web site. The most recent versions of samples are available there.

For more information, see Visual Studio Samples.

Note

This sample is only available online.

To run the client application in Visual Studio

  1. Open the file LinqToTerraServerProvider.sln in Visual Studio.

  2. In Solution Explorer, right-click the LinqToTerraServerProvider project and then click Build.

  3. On the Debug menu, click Start Without Debugging.

Requirements

You need the following components to run this sample:

  • Visual Studio 2008

Demonstrates

This sample demonstrates how to implement IQueryable<T>, IOrderedQueryable<T>, and IQueryProvider.

Design Decisions

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

  • A method call expression for the method StartsWith, for example place.Name.StartsWith("Seat").

  • A method call expression for the methods Enumerable.Contains and 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 that the client query defines queries against. This type implements IOrderedQueryable<T> to support sort operations in the query. Because IOrderedQueryable<T> derives from IQueryable<T>, by implementing IOrderedQueryable<T> this type also implements IQueryable<T>.

TerraServerQueryContext.cs

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

TerraServerQueryProvider.cs

Contains the type that implements the IQueryProvider interface. The methods that this interface defines are called by the standard query operator methods that are defined in 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 Walkthrough: Creating an IQueryable LINQ Provider.

See Also

Tasks

How to: Implement an Expression Tree Visitor

Other Resources

LINQ C# Samples