New Posts New Posts RSS Feed: OData Projection
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

OData Projection

 Post Reply Post Reply
Author
smi-mark View Drop Down
DevForce MVP
DevForce MVP
Avatar

Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
Post Options Post Options   Quote smi-mark Quote  Post ReplyReply Direct Link To This Post Topic: OData Projection
    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.
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post 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) 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 ....
Back to Top
smi-mark View Drop Down
DevForce MVP
DevForce MVP
Avatar

Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
Post Options Post Options   Quote smi-mark Quote  Post ReplyReply Direct Link To This Post 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.




Edited by smi-mark - 11-Jan-2012 at 7:45am
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 11-Jan-2012 at 10:23am
Very cool.  Thanks for sharing this.
Back to Top
smi-mark View Drop Down
DevForce MVP
DevForce MVP
Avatar

Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
Post Options Post Options   Quote smi-mark Quote  Post ReplyReply Direct Link To This Post 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 :)



Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down