Monday, August 24, 2015
A more straightforward and convenient way to query data using LINQ with ObjectSpace
First of all, it is important to note that the capability to query data using LINQ has been available for a long time in the current version of XAF (or better said, in the underlying Entity Framework and XPO ORM libraries). So, this improvement in v15.2 is all about improving developer usability by exposing a helper method for the IObjectSpace interface representing one of the main XAF entities (learn more...).
As noted in the corresponding SC ticket (from here you can also learn on the current solution):
The IObjectSpace interface now declares the following method:
In the NonPersistentObjectSpace, the GetObjectsQuery method casts the collection of objects created in the ObjectsGetting event to IQueryable and returns the result.
For XPObjectSpace, this method just returns a new XPQuery<T> from the underlying Session, while for the EFObjectSpace, the GetObjectsQuery method returns a new instance of ObjectQuery<T> with the help of the associated DbContext.
Here are a few usage examples from our unit tests (using the method-based query syntax):
IQueryable<Product> objectsQuery = objectSpaceB.GetObjectsQuery<Product>().Where(p => (p.Supplier.ID == supplier_A.ID));
Assert.AreEqual(3, objectsQuery.Where(p => (p.Name == "A")).Count());
Assert.AreEqual(2, objectsQuery.Where(p => (p.Name == "B")).Count());
IQueryable<TestObject> query = objectSpaceB.GetObjectsQuery<TestObject>();
Assert.AreEqual(3, query.Where(t => t.StringProperty == "A").Count());
Assert.AreEqual(2, query.Where(t => t.StringProperty == "B").Count());
I hope you will appreciate this minor improvement and it will save you from polluting your code by the casts to the XPObjectSpace/EFObjectSpace types to access the underlying ORM data context LINQ features.