3

I need to create a WCF service to return objects queried from a database through Entity Framework. Most articles I've read suggests that I should create a method for each type of query. But I think this will cause an explosion in the number of methods I will create, for example:

  • GetAllCars()
  • GetCarsByBrand(string brandName)
  • GetCarsByYear(int year)
  • GetCarsByBrandAndYear(string brandName, int year)
  • GetCarsByTireSize(float tireSize)
  • GetCarsByEngineType(string engineType)
  • GetCarsByEngineSizeAndType(float engineSize, string engineType)
  • GetCarsByEngineSizeBetween(float lowerEngineSize, float upperEngineSize)
  • etc..

On top of that, if a new query is required, then I will have to create a new method to supoport it.

There must be a better more generic way to do this. What would be ideal is if the client can create an expression tree via LINQ, send it over WCF, then run the query through entity framework. Then I can have one method to support all queries. For example:

  • QueryCars(Expression expression)

Or send an expression as a string:

  • QueryCars(string expression)

How have developers solved this problem of flexible querying?

I am currently working in .NET 4.0. Security is not really a concern since this is just an internal app.

Mas
  • 4,546
  • 5
  • 39
  • 56

2 Answers2

3

By your describtion you don't need pure WCF services but WCF Data Services instead. Data service allow you exposing IQueryable and define the Linq query on the client.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
3

What you're looking for is WCF Data Services. It uses the OData protocol to query the data with Linq.

Example with the Stack Overflow OData service:

var query = from u in service.Users
            orderby u.Reputation descending
            select u;

Console.WriteLine ("Top ten Stack Overflow users");
foreach (var u in query.Take(10))
{
    Console.WriteLine ("{0}: {1}", u.DisplayName, u.Reputation);
}

In the code above, service.Users is of type IQueryable<User>, which allows you to query it with an expression tree.

You can easily try the SO service with LINQPad, or by adding a reference to the service URL in a VS project.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • This looks like the answer I'm looking for. Out of curiosity, how would have this problem been solved before WCF Data Services? – Mas Jan 11 '11 at 11:44
  • After reading a bit about this, I'm unclear whether this would also support lazy loading. Do you know if lazy loading is automatically handled? – Mas Jan 11 '11 at 11:46
  • @Mas: Before it, it was called ADO.NET Data Services or Astoria and before it Linq doesn't exist ;) – Ladislav Mrnka Jan 11 '11 at 11:46
  • 2
    @Mas: Automatic lazy loading over service is pretty bad idea. You can use special extension method Expand on collections or call LoadProperty. – Ladislav Mrnka Jan 11 '11 at 11:51
  • I went through an example, and I see that related objects must be explicitly loaded from the database. I agree, lazy loading is a bad idea in this case. – Mas Jan 11 '11 at 12:46
  • The OData link is broken. – Cœur Aug 29 '17 at 13:53