The One With

OData Provider for XPO - IDataServiceQueryProvider

In the previous post, we have introduced a WCF Data Service Provider for XPO. Let’s now look at how it works under the hood.

For a basic read-only data service provider we only need to implement two interfaces:

  • IDataServiceMetadataProvider : Provides the metadata information about your entities. The data service will query this for your resource types, resource sets etc…
  • IDataServiceQueryProvider : Provides access to the actual entity objects and their properties. Most importantly, it is responsible for the IQueryable on which data operations like $filter, $orderby, $skip are performed.

Custom provider implementations are picked up via IServiceProvider.GetService

public class XpoDataService : DataService<XpoDataContext>, IServiceProvider {
    XpoProvider _provider;
    public XpoProvider GetProvider() {
        if (_provider == null) {
            _provider = newXpoProvider(this);
        return _provider;
    object IServiceProvider.GetService(TypeserviceType) {
        if (serviceType == typeof(IDataServiceMetadataProvider)
            || serviceType == typeof(IDataServiceQueryProvider)) {
            return GetProvider();
        } else {
            return null;


Implementing the IDataServiceMetadataProvider for XPO metadata is very straightforward. We already have all information needed in the form of XPClassInfo/XPMemberInfo. It’s just a matter translating it into ResourceTypes/ResourceProperties constructs.

XPClassInfo classInfo = Dictionary.QueryClassInfo(entityType);
if (classInfo == null) {
    return null;


foreach (XPMemberInfo memberInfo in classInfo.Members) {
    AddProperty(resourceType, memberInfo);

Than, if we want to make a specific entity queryable, we’ll create a resource set of it.

if (resourceType.ResourceTypeKind == ResourceTypeKind.EntityType) {

By default, our data provider will automatically do all of this for *all* XPO classes found in the assembly where the data service lives. You can control this behavior by overriding the RegisterClasses method.

public override void RegisterClasses(XpoProviderMetadata metadata) {


Implementation of IDataServiceQueryProvider is centered around it’s GetQueryRootForResourceSet method. This is where we return an IQueryable root on which data service will apply the request criteria. Now because XPO already has a LINQ implementation, all we need to return is an XPQuery<T> : IQueryable<T>.

public class XpoQueryBridgeFactory<T> : IXpQueryBridgeFactory {
    public object Create(Session session) {
        return new XPQuery<T>(session);

public virtual IQueryable GetQueryRootForResourceSet(ResourceSet resourceSet) {
    IXpQueryBridgeFactory factory = (IXpQueryBridgeFactory)Activator.CreateInstance(
    return (IQueryable)factory.Create(this.Session);

Note: The real query root has an intercepting LINQ to LINQ wrapper to deal with special cases. 

What’s next?



Published May 26 2010, 10:22 AM by
Filed under: , ,
Bookmark and Share


No Comments

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at or call us at +1 (818) 844-3383


DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners