Project Description
LinqToolkit is a lightweight class library.
It is designed to help create custom Linq providers.

Class Query based on IQueryable Tales - LINQ to LDAP from Bart De Smet's online blog

Please take a look on LinqToolkit.Test project for usage examples.


To create custom provider you need to implement several interfaces and inherit from Query class.


IQueryContext provides for Query object:
  • Factory methods to create operations for Where operator:
    • JoinOperation ( AndAlso, OrElse )
    • UnaryOperation ( Not, MemberAccess )
    • BinaryOperation ( Equal, NotEqual, Multiply, Add and so on )
    • CallOperation ( Contains, StartWith and so on )
  • Factory methods to build custom operators:
    • Without parameters
    • With property parameter
    • With constant value parameter
IQueryOptions provides for Query object:
  • Filter expression property for Where operator
  • Array of properties to read from data source

IBaseOperation and IJoinOperation interfaces help to build Where operator.

Query class example:
public class CustomQuery<TEntity>: Query<CustomQueryContext, TEntity> {
        protected override Query<QueryContext, T> Copy<T>() {
            return new CustomQuery<T>();
        protected override IEnumerable<object> ExecuteRequest() {
            var options = this.Context.Options;
            return result;


Gives a custom name for data source. By default data source has a name of TEntity class. This data source name is stored in IQueryOptions.Source property.

Gives a custom name for a data source property. By default property names are the same as TEntity property and field names. Data source property names are stored in IQueryOptions.PropertiesToRead property.

Says to Query class to ignore properties or fields for which this attribute is assigned.

SimpleQuery namespace

Use SimpleQuery.QueryContext for simple providers:
It contains implementation for IQueryContext and IQueryOptions interfaces.
Using this context you do not need to create custom query context and options, but only inherit from Query class.
Property Options gives an access to:
  • Filter - parsed WHERE operator
  • PropertiesToRead - property names based on SELECT operator
  • Operators - other operators applied to query (Distinct, Take etc.)

Use Query.Where( BaseOperation ) to build conditions dynamically:
var filter =
    new JoinOperation( ExpressionType.AndAlso,
        new BinaryOperation( ExpressionType.GreaterThan, "PropertyName", 10 ),
        new UnaryOperation( ExpressionType.Not, "FieldName" )
result =
    from item in new SomeQuery()
    where filter
    select item;

It is possible to apply additional conditions:
result =
    from item in new SomeQuery()
    where filter
    where item.Name.Contains("abc")
    select item;

result =
    new SomeQuery()
    .Where( filter )
    .Where( item => item.Name.Contains("abc") );

Use QueryOptions.Transform for XSL transformation:

Using this extension you can transform options e.g. to SQL query.
LinqToolkit\SimpleQuery\QueryOptions.xsd - describes the query options xml scheme.
LinqToolkit.Test\Extensions\Sample.xslt - gives a sample for XSL transformation.

Michael Borisov.

Last edited Apr 9, 2009 at 4:10 AM by corker, version 24