views:

559

answers:

1

I am trying to build an ADO.NET Data Service with lots of entities and a few service operations. On one side I created a ASP.NET Web Application, in which an ADO.NET Entity Data Model and an ADO.NET Data Service are located. On the other side I created a second ASP.NET Web Application that has a Service Reference to the Data Service.

Entities are coming through very well, I can use LINQ to retrieve the data I want:

TestEntities entities = new TestEntities(
      new Uri("http://localhost/service/service.svc"));

var query = from customer in entities.Customers
        where customer.ID == 1234
        select customer;

query.ToList();

This works. However, retrieving information through Service Operations completely eludes me. Data Service-side code:

public static void InitializeService(IDataServiceConfiguration config) {
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
    config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}

[WebInvoke]
public IQueryable<Customer> GetSomeCustomers() {
    TestEntities entities = new TestEntities();
    return from customer in entities.Customers
        where customer.ID > 0 && customer.ID < 20
        select customer;
}

When I added the Service reference to my client project, Visual Studio didn't pick up on any Service Operations. I know I can access them through constructed URIs and the BeginExecute method of either the DataServiceContext object or the TestEntities object (in this case), or something like that, but that is not how I want it.

What I want is to use LINQ to go through the returned data of the Service Operation. Is this possible? It should be, right?

+3  A: 

Simple stuff once you know.

Just a few things to know:

Currently DataServiceClientGenerator (which uses the EntityClassGenerator) doesnt create methods for the service operations.

Using CreateQuery method on the context is not supported for service operations, currently they work because there is no validation on the client side for that (you will notice that if you use CreateQuery the "()" is added to the end of the Query Method like this "http://localhost/service.svc/method()?parameter=2", you can use CreateQuery but it is not recommended.

Not all Service operations return values, but for this example i will only show an example for the ones that do.

public partial class NorthwindEntities
{ 
    public IQueryable<Order> OrdersByRegion(int regionId)
    {
     return this.Execute<Orders>(new Uri(string.Format("{0}OrdersByCountry?regionId={1}", this.BaseUri, regionId), UriKind.RelativeOrAbsolute));
    }
}

If you require more information please feel free to ask any questions.

PS.: On your example you dont need to create a new data context on your service operation (server side) the DataService has already a reference instantiated when the service is called.

You can actually override the create of the data context on the service side like this:

protected override NorthwindEntities CreateDataSource()
{
     return new NorthwindEntities();
}
dmportella
Ok, but how do you invoke the "OrdersByRegion" operation from client side? Do you have to build the REST URL (e.g. http://server/service.svc/OrdersByRegion?regionId=1) by hand? Thanks.
Ciprian Bortos
Hi Ciprian, yes unfortunately you do. string.format is usually the best to use. see my first code example it demonstrate how to call it
dmportella