my6solutions

asp .net, the social web & other distractions

 

Running Apps

Disclaimer

I am in no way affiliated with Microsoft or Google. I am just another developer trying to make a difference. All opinions and observations are usually my own.

Strongly-typed Dynamic LINQ via Expressions and Reflection

LINQ to SQL is a neat way to do your SQL queries under ASP .NET. It is so good that I have used it until a stage where I cannot remember my T-SQLs. But then that probably is just me, my memory isn't very kind to me. However, one of the problems with LINQ is that it is not very flexible when you want to have the option of creating queries on the fly. This is especially true in situations where you have to query a database based on certain fields that are specified by the user.

One of the solution to this problem is the Dynamic LINQ library. Scott Guthrie has a blog entry about this dynamic LINQ library here. Another way of doing this is using LINQ Expressions.

The following is the class used to do this via the Expression way

public static class LinqToSQLExtension

{

    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)

    {

        return ApplyOrder<T>(source, property, "OrderBy");

    }

    public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property)

    {

        return ApplyOrder<T>(source, property, "OrderByDescending");

    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property)

    {

        return ApplyOrder<T>(source, property, "ThenBy");

    }

    public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property)

    {

        return ApplyOrder<T>(source, property, "ThenByDescending");

    }

    static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source, string property, string methodName)

    {

        string[] props = property.Split('.');

        Type type = typeof(T);

        ParameterExpression arg = Expression.Parameter(type, "x");

        Expression expr = arg;

        foreach (string prop in props)

        {

            PropertyInfo pi = type.GetProperty(prop);

            expr = Expression.Property(expr, pi);

            type = pi.PropertyType;

        }

        Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);

        LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

 

        object result = typeof(Queryable).GetMethods().Single(

                method => method.Name == methodName

                        && method.IsGenericMethodDefinition

                        && method.GetGenericArguments().Length == 2

                        && method.GetParameters().Length == 2)

                .MakeGenericMethod(typeof(T), type)

                .Invoke(null, new object[] { source, lambda });

        return (IOrderedQueryable<T>)result;

    }

}

 

Bookmark and Share

Tags:
Categories: ASP .NET
Permalink | Comments (0) | Post RSSRSS comment feed