Dynamic configurable and resuable Linq

How to get past of writing static linq statements? Or how to include the parameters in your linq query? Or write your linq dynamically in order for it to be configurable and reusable?

1.Relationships and differences of delegate, expression and func

	   delegate int del(int i);

        private void button2_Click(object sender, EventArgs e)
        {

            del myDelegate = x => x * x;
            int j = myDelegate(5); //j = 25

            Func<int, int> myFunc = x => x*x ;

            j = myFunc(5);

            Expression<del> myET = x => x * x;

            del  myETFunc = myET.Compile();

            j = myETFunc(5);

            Expression<Func<int, int>> myExp = x => x * x;


            Func<int, int> myExpFunc = myExp.Compile();

            j = myExpFunc(5);

           
        }

Func, input is int, and output is int too, the last generic is output type, the original type is:

public delegate TResult Func<in T, out TResult>(T arg)

As an extreme, there is a type like this:


public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out TResult>(
	T1 arg1,
	T2 arg2,
	T3 arg3,
	T4 arg4,
	T5 arg5,
	T6 arg6,
	T7 arg7,
	T8 arg8,
	T9 arg9
)

2. Dynamic Linq

   private void button3_Click(object sender, EventArgs e)
   {
            Entities db = new Entities();

            Log log = db.Logs.Where(p => p.log_code == 1).FirstOrDefault();

            log = db.Logs.Where(FuncWhere(1)).FirstOrDefault();

            log = db.Logs.Where(ExpressionFuncWhere(1)).FirstOrDefault();
    }


        private Func<Log, bool> FuncWhere(int logcode)
        {
            Func<Log, bool> exp = p => p.log_code == logcode;

            return exp;
        }

        private Expression<Func<Log, bool>> ExpressionFuncWhere(int logcode)
        {
            Expression<Func<Log, bool>> exp = p => p.log_code == logcode;

            return exp;
        }
 

3. Expression or Func

Using Expression you are explicitly creating an expression tree – this means that you can deal with the code that makes up the query as if it were data.

4. Find the delegate type from system.linq

As an example of where implementation

public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);

Where is an extension method.

Type inference from this key word for the data set where is applied on.

Be aware of overloads

In System.Linq. Queryable, there are all sorts of Linq methods you can customize or make them dynamic according to your program needs, methods like : sum, orderby,selectmany etc

5. Expression Trees or not

When you need to combine query variables you might want to build your expression tree programmatically using expression tree, there is not an easy way, but I find it comfortable to just code my lambda in a static way.

  private void button1_Click(object sender, EventArgs e)
        {
            Entities db = new Entities();

            Log log = db.Logs.Where(p => p.log_code ==1 && p.log_text.Contains("Error") ).FirstOrDefault();

            log = db.Logs.Where(FuncCombinedWhere(1,"Error")).FirstOrDefault();

        }
        private Func<Log, bool> FuncCombinedWhere(int logcode, string textseearch)
        {
            Func<Log, bool> exp = p => false;

            if (logcode != 0 && !string.IsNullOrEmpty(textseearch))
            {
                exp = p => p.log_code == logcode && p.log_text.Contains(textseearch);
            }
            else if (logcode != 0)
            {
                exp = p => p.log_code == logcode;
            }
            else if (!string.IsNullOrEmpty(textseearch))
            {
                exp = p => p.log_text.Contains(textseearch);

            }

            return exp;

        }

6. Reuse Linq through IQueryable type

public IQueryable<Log> AllErrorLog()
{
 return from log in db.Logs.where(p=>p.log_level==1) select log;
}

AllErrorLog() can be used for contructing other queries.

Have fun.

Tags:

This entry was posted on Tuesday, February 7th, 2012 at 7:21 am and is filed under ASP.NET. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

*