Question

I've been learning about IQueryable and lazy loading/deferred execution of queries.

Is it possible to expose this functionality over WCF? I'd like to expose a LINQ-to-SQL service that returns an IQueryable which I can then perform additional queries on at the client, and finally execute using a .ToList(). Is OData format applicable at all in this context?

If possible, what is the term for this technique and what are some good tutorials I can follow? Thank you.

Was it helpful?

Solution

You should check WCF Data Services which will allow you to define Linq query on the client. WCF Data Services are probably the only solution for your requirement.

IQueryable is still only interface and the functionality depends on the type implementing the interface. You can't directly expose Linq-To-Sql or Linq-To-Entities queries. There are multiple reasons like short living contexts or serialization which will execute the query so the client will get list of all objects instead of the query.

OTHER TIPS

as far as i know, the datacontext is not serializable meaning that you cannot pass it around with WCF

You can use http://interlinq.codeplex.com/ which allows you to send Linq query over WCF.

WCF Data Services only can be using with webHttpBinding and not all Linq queries can be expressed. Writing queries when WCF Data Service is used is not so attractive - requires string expressions such as:

.AddQueryOption("$filter", "Id eq 100");

https://remotelinq.codeplex.com/ is another choice. But it works in AppDomain to scan the Current Assemblies and serialize them. This tech is not suitable to WinRT as no Domains for WinRT App

I've been struggling with the same question, and realized that a well formed question is a problem solved.

IQueryable basically serves to filter the query before sending it to your DB call so instead of getting 1000 records and filter only 10, you get those 10 to begin with. That filtering belongs to your Service Layer, but if you are building an API I would assume you would map it with AND/OR parameters in your URL.

http://{host}/{entity}/q?name=john&age=21.

So you end up with something like this:

Filter:Column1=Value1 > http://{host}/{entity}q?column1=value1 >  SELECT *
                                                                  FROM  Entity
                                                                  WHERE Column1=Value1

MVC                   > WCF                                    >  DB

You can find a very good sample [here]

Lastly, since your payload from the WCF will be most likely a JSON, you can (and should) then deserialize them in your Domain Models inside a collection. It is until this point where the paging should occur, so I would recommend some WCF caching (and since its HTTP, it's really simple). You still will be using LINQ on the WebApp side, just w/o "WHERE" LINQ clause (unless you want to dynamically create the URL expressed above?)

For a complex OR query, you mind end up with multiple WCF queries (1 per "AND") and then concatenate them all together

If it's possible to send IQuerable<> over WCF it's not a good thing security wise, since IQuerable<> could expose stuff like the connection string to the database. Some of the previous comments seem promising though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top