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
-
Posted by JudahGabriel on 3/20/2010 6:41 PM
Cool. We're excited to see continued investment in LINQ; we feel LINQ is the most natural query syntax around, can't beat it. Glad to see DB4O feels LINQ is important as well.
-
Posted by sinae on 3/20/2010 6:41 PM
How can i have this feature??? And when will it be included in the stable build??
I find it very important because right now my repository have to iterate tru all item create an ienumeration and cast it to IQueryable with the AsQueryable method.
So i'm not sure but I think to call AsQueryable directly on the container will be a lot better because if i have a where clause on the result it will not retrieve everything from the database just what is needed.
So my repository will just delegate to the container directly.
lot better :)
-
Posted by Anonymous on 3/20/2010 6:41 PM
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Loading, please waiting...