Print Page | Close Window

OData Projection

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3207
Printed Date: 13-May-2026 at 11:29am


Topic: OData Projection
Posted By: smi-mark
Subject: OData Projection
Date Posted: 10-Jan-2012 at 3:47pm
Is there a way of using projections with OData? I'm working on a sample HTML5 app and I'd like to build a projection from a few entities and a stored procedure, then return this to the client. I know you can use views and such, but haven't seen anything about projections yet.



Replies:
Posted By: kimj
Date Posted: 10-Jan-2012 at 6:42pm
Sure.  DevForce has supported anonymous projections with OData since version 6.0.9.  I guess it might depend on which Javascript library you're using, but you can check out our OData.js sample ( http://drc.ideablade.com/xwiki/bin/view/Documentation/code-sample-odata-js - http://drc.ideablade.com/xwiki/bin/view/Documentation/code-sample-odata-js ) which uses jQuery and datajs.  The sample isn't using anonymous projections, but just add a "$select=" clause to a query.  For example, "Customers?$select=CustomerId, CompanyName".
 
I'm not so sure about a projection from a stored procedure though ....


Posted By: smi-mark
Date Posted: 10-Jan-2012 at 7:33pm
It's all working now :)

I created my projection class and marked it with the DataServiceKey. Then in my service I added this:

        [WebGet]
        public IQueryable<AccountProjection> SearchAccounts(string searchText)
        {
            var accounts = this.CurrentDataSource.Accounts
                .Where(a => a.TaxAccountNumber.Contains(searchText))
                .Select(a => new AccountProjection
                                 {
                                     AccountId = a.AccountId,
                                     TaxAccountNumber = a.TaxAccountNumber
                                 }).ToList();

//Use my procedure to get the info I need and update the projection
           return accounts.AsQueryable();         }

Then under InitializeService I added this line:
config.SetServiceOperationAccessRule("SearchAccounts",ServiceOperationRights.AllRead);
Now I can do whatever I want to get the data, and return the projection class.




Posted By: kimj
Date Posted: 11-Jan-2012 at 10:23am
Very cool.  Thanks for sharing this.


Posted By: smi-mark
Date Posted: 11-Jan-2012 at 3:03pm
I was upset when I read that you can't use navigation properties on ComplexTypes with WCF.

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/b9e14bc6-b248-48e1-b9e3-af7600537110

With DevForce I was able to get it to work.

My complex types look like this:

AccountProjection
      int AccountId
      IEnumerable<ReceivableProjection> Receivables

ReceivableProjection
     int ReceivableId

By default, this will not work, you will get this error:

The server encountered an error processing the request. The exception message is 'The property 'Receivables' on a complex type 'AccountProjection' is not a valid property. Navigation properties are not supported on complex types.'. See server logs for more details.

To get past this I have simply added this to my entity manager partial class:

    public EntityQuery<ReceivableProjection> ReceivableProjections
    {
        get { return null; }
    }
 
    public EntityQuery<AccountProjection> AccountProjections
    {
        get { return null; }
    }

Then I added this to my web service in InitializeService:

            config.SetEntitySetAccessRule("ReceivableProjections"EntitySetRights.All);             config.SetEntitySetAccessRule("AccountProjections"EntitySetRights.All);

Now it works, as long as I make sure to use $expand=Receivables in my query :)






Print Page | Close Window