Thursday, July 17, 2008

I likz demz linq

So today I had this weird need to try creating a sort of dynamic linq thing in which I could query a User list but not have to write a Linq query for every method. I just wanted to make a method that would return the correct query that I wanted based on a simple "dynamic" where clause. Well part of the reason this should be easy is if you look at the Where extension method on an IEnumerable collection, you will see it needs a Func<T, K> where T is the type of the items in the list. So ding!, create a method that takes in a Func<User, Boolean> and puts it in them thar where clause. Then you could easily use a lambda expression to create the Func. At first you might thing something like this:
private static IQueryable<User> GetUserList(Func<User, Boolean> whereClause)
{
  var query = from user in Users
            where whereClause(user)
            select user;

  return query;
}

public static IList<User> GetUserListByUserName(String userName)
{
  return GetUserList(currentUser => currentUser.UserName == userName).ToList();
}
AND YOU WOULD BE WRONG! I only know this because... eh... I saw a friend of mine try this and it failed. Fact is, the Linq where doesn't take in a Func, but rather it expects and Expression. So no big deal right? Slap on an expression and go... except you can't keep the same syntax. (Trust me, my... friend tried) Being the absolute genius that I am, I offered my friend a solution, and it's slightly ugly:
private static IQueryable<User> GetUserList(Expression<Func<User, Boolean>> whereClause)
{
  var query = (from user in Users
            select user).Where(whereClause);

  return query;
}
Could be used like:
public static IList<User> GetUserList()
{
  return GetUserList(currentUser => true).ToList();
}
Or
public static IList<User> GetUserListByFirstName(String firstName)
{
  return GetUserList(currentUser => currentUser.FirstName == firstName).ToList();
}
Yeah, not the prettiest of things, but it is what it is. I'm not even sure this is useful yet. Still screwing around with it. Does cut down on code for easy queries. AND NOW FOR THE ASSEMBLIES!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

No comments: