The LINQ framework design guidelines [1] describes the "... three means by which a type can be designed to participate in LINQ queries: implementing IEnumerable<> ..., implementing IQueryable<>, or by defining the Query Pattern on the type".

For db4o we chose the Query Pattern implementation because only a subset of the available LINQ operators could be reasonably supported. By implementing the pattern for the operators we support any code that references an unsupported operator automatically falls back to LINQ to Objects.

Yes, implementing IQueryable<> [2] used to be that slightly more complicated approach recommended when most LINQ operators were supported by the provider. Things have changed and IQueryable<> is now being used by APIs everywhere as the lowest common denominator for optimizing LINQ providers.

Which is why we decided to make LINQ to db4o support the IQueryable interface as well.

Just as with LINQ to db4o, it's very easy to use and completely integrated:

        using Db4objects.Db4o.Linq;

// ...

IObjectContainer container = Db4oEmbedded.OpenFile("HR.db4o");
IQueryable<Person> query = container.AsQueryable<Person>();


Et voila, you can pass `query` around as an IQueryable/IQueryable reference to every API which is dynamically manipulating a LINQ query using the IQueryable interface or the Queryable extension methods.

Shall a scalar method be called on this IQueryable or shall it be iterated over, the underlying implementation will rewrite the query expression tree into an optimized LINQ to db4o query. For the unsupported operators the query would still fallback to LINQ to Objects, meaning that all Queryable methods can be used without distinction.

We'll see in a next post how we've leveraged our IQueryable implementation to support an API which actually demands it.

[1] http://blogs.msdn.com/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx
[2] http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx

 

Note: if you want to check out a demos that use these new features see this page

        using Db4objects.Db4o.Linq;

// ...

IObjectContainer container = Db4oEmbedded.OpenFile("HR.db4o");
IQueryable<Person> query = container.AsQueryable<Person>();


Et voila, you can pass `query` around as an IQueryable/IQueryable reference to every API which is dynamically manipulating a LINQ query using the IQueryable interface or the Queryable extension methods.

Shall a scalar method be called on this IQueryable or shall it be iterated over, the underlying implementation will rewrite the query expression tree into an optimized LINQ to db4o query. For the unsupported operators the query would still fallback to LINQ to Objects, meaning that all Queryable methods can be used without distinction.

We'll see in a next post how we've leveraged our IQueryable implementation to support an API which actually demands it.

[1] http://blogs.msdn.com/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx
[2] http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx

Note: if you want to check out a demo using this new feature see this page