RSS

Using Linq expressions in a client-server application.

Thu, Jul 16, 2009

Staff Posts, Tips and Tricks

Imagine the following situation:

  • A client-server application, where the client side has no knowledge of the DAL. Even the DAL assemblies are not found on the client side.
  • The client should have an API to fetch entities using some flexible criteria.

One of the likable ways to satisfy the second bullet is let the client specify Linq expressions, pass them to the server side and let the DAL handle it. The benefits are clear:

  • No need to invent criteria API. Granted, some DAL implementations may come with versatile in-house criteria API. However, one of the requirements is that the client side be unaware of the actual DAL, so it may not use any DAL specific criteria API.
  • The multitude of DAL implementations consuming Linq expressions – Linq to SQL, Linq to Entities, Linq to NHibernate to name a few.

So, this is the way we have chosen. Ideally we would like the following client side code to be valid:

public static IList<Entity> GetByNamePattern(string namePattern)
{
Expression<Func<Entity, bool>> expr = e => e.Name.Contains(namePattern);
return EntityCollection<Entity>.FetchByExpression(expr);
}

The process seems to be pretty straightforward:

  1. Serialize the Linq expression
  2. Send it over the wire
  3. Deserialize the Linq expression
  4. Pass it to the DAL to receive a list of entities
  5. Return the entities to the client

There is, however, a problem – linq expressions are not easily serializable! See this msdn forum post, for instance.

There are couple of ways to deal with it. I will describe here ours.

First, the linq expression has to be partially evaluated to remove any anonymous delegates and resolve any member/property access references, which can be evaluated immediately. There is an excellent post by Matt Warren here, which explains exactly this. But I have found that the DAL implementation we use, namely Linq to NHibernate, already has a partial linq expression evaluator, which looks very similar to the  Matt Warren’s code. I suppose they have read his post very thoroughly. So, I just took their partial linq evaluator code – two totally self contained C# source code files, one for the Evaluator and the other for the Expression Visitor, also explained by  Matt Warren in the Appendix to his post here.

Next, the partially evaluated Linq expression must be converted to something easily serializable. Again, there are several solutions out there, but I have choosen the one shared with the community by Luca Bolognese and LukeH here. It allows one to (de)serialize a linq expression to/from XML.

Having these two pieces makes it possible to transmit a linq expression from the client side to the server side.

There is one last thing. How to use a linq expression with Linq to NHibernate? After all, their samples only give this kind of code – from c in db.Customers where linq-expression select c.

Actually, it turns out to be pretty simple – db.Customers.Where(linq-expression), where the client side is responsible for supplying the linq-expression and the server side has access to db.Customers.

That’s it.

, , , ,

share

1 Comments For This Post

  1. Shunrasoftware (Shunra Software) Says:

    Using Linq expressions in a client-server application. http://tinyurl.com/mp9ybh

Leave a Reply

Get Adobe Flash playerPlugin by wpburn.com wordpress themes