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
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
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
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: LINQ
