Generally if the logic is relatively simple, there are more than one query condition, and some situations do not need to add the query condition
Simple way to do it.
Public iqueryable<fileimport> dynamicchainedsyntax
(iqueryable<fileimport> files, bool pastOnly)
{
var query = files. Where (file => file. Importdate >
DateTime.Now.AddDays ( -7));
if (pastonly)
query = query. Where (file => file. Importdate <
datetime.today);
return query;
The multiple where condition here is an and relationship, and if it is a relationship, you can combine the results of multiple queries to union
Of course, most of the time, we want to be able to dynamically build query conditions, you can be any field for any operator-type query, the relationship between the different query conditions can be dynamically defined.
Now that the expression tree comes in handy, the basics of the expression tree are mentioned in the previous article.
The main point here is how to construct the Where query condition in LINQ, but it is simply familiar with other methods provided by the expression tree.
Public Func<tsource, bool> simplecomparison<tsource>
String, object value
{
var Type = typeof (TSource);
var pe = expression.parameter (Type, "P");
var propertyreference = Expression.property (PE, property);
var constantreference = expression.constant (value);
Return Expression.lambda<func<tsource, Bool>>
(expression.equal (PropertyReference, constantreference),
new[] {PE}). Compile ();
}
Oh, words to here, look at my little demo
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Linq.Expressions;
Using System.Text;
Using System.Threading.Tasks; Namespace ConsoleApplication1 {class Program {static void Main (string[] args) {//(a , b) => (A+B)//Parameter construction (defines the name and parameter type of the parameter) parameterexpression EXP1 = Expression.parameter (typeof (int)
, "a");
ParameterExpression exp2 = Expression.parameter (typeof (int), "B");
The construction of the expression subject binaryexpression exp = Expression.add (EXP1, EXP2); The construction of an expression tree (defined below, the type of the expression is the type of the lambda//lambda expression is func<int, int, int>) var lambda = expression.la
Mbda<func<int, int, int>> (exp, EXP1, EXP2);
P=>p.name can be dynamically constructed by parameterexpression Exp3 = Expression.parameter (typeof (Person), "P");
var property = Expression.property (Exp3, "Name"); var lambda2 = Expression.lambda<func<perSon, String>> (property, EXP3); P=>p.name = = "Daisy" list<person> persons = new List<person> () {new person () { Name = "Daisy", age = ten}, new Person () {Name = ' daisy ', age = A, new person () {name= "Dom"
, age=12}, new Person () {name= "Caren", age=10}};
var compareexp = simplecompare<person> ("Name", "Daisy"); var Daisys = persons. Where (COMPAREEXP).
ToList (); foreach (var item in Daisys) {Console.WriteLine ("Name:" +item.)
Name+ "Age:" +item.age);
} console.readkey ();
public static Func<tsource, bool> simplecompare<tsource> (String, object value) {
var type = typeof (TSource);
var pe = expression.parameter (Type, "P");
var propertyreference = Expression.property (PE, property); var constantreference = EXpression.
Constant (value); Compile is an interface to the expression that generates the delegate return expression.lambda<func<tsource of the LAMBDA expression tree pair, bool>> (expression.equ Al (PropertyReference, constantreference), PE).
Compile ();
public class Person {public string Name {get; set;}
public int Age {get; set;}
}
}
Let's look at the results of the query:
Well, it's very simple to understand, which is to build an expression tree that returns the type of delegate we need.
And then I'm going to punch you!
Dynamic build expression tree, best practice version, very practical.
public class filtercollection:collection<ilist<filter>>
{public
filtercollection ()
: base ()
{}
} public
class Filter
{public
string propertyname {get; set;}
Public Op Operation {get; set;}
Public object Value {get; set;}
}
Public enum Op
{
Equals,
GreaterThan,
LessThan,
greaterthanorequal
, Lessthanorequal,
Contains,
startswith,
EndsWith
}
Through the above class can dynamically build complex query conditions, the following specific invocation of the class OH
Using Infrastructure.model;
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Linq.Expressions;
Using System.Reflection;
Using System.Text;
Using System.Threading.Tasks; namespace Infrastructure.operation {public static class Lambdaexpressionbuilder {private static Methodin Fo Containsmethod = typeof (String).
GetMethod ("Contains"); private static MethodInfo Startswithmethod = typeof (String).
GetMethod ("StartsWith", new type[] {typeof (String)}); private static MethodInfo Endswithmethod = typeof (String).
GetMethod ("EndsWith", new type[] {typeof (String)}); private static Expression getexpression (parameterexpression param, filter filter) {memberexpression m Ember = Expression.property (param, filter.
PropertyName);
Expression Handledmember = member; CONSTANTEXPRESSION constant = expression.constant (filter.
Value);
if (member. Member.membertype = = membertypes.property) {Type propertytype = ((PropertyInfo) member. Member).
PropertyType; if (propertytype = = typeof (String)) {Handledmember = Expression.call (Member, typeof (S Tring).
GetMethod ("ToLower", System.Type.EmptyTypes));
} if (propertytype = = typeof (DateTime)) {Handledmember = Expression.property (Member, typeof (DateTime).
GetProperty ("Value")); } switch (filter. Operation) {case Op.Equals:return expression.equal (Handledmember, Consta
NT);
Case Op.GreaterThan:return Expression.greaterthan (Handledmember, constant);
Case Op.GreaterThanOrEqual:return expression.greaterthanorequal (Handledmember, constant); Case Op.Lessthan:return Expression.lessthan (Handledmember, constant);
Case Op.LessThanOrEqual:return expression.lessthanorequal (Handledmember, constant);
Case Op.Contains:return Expression.call (handledmember, Containsmethod, constant);
Case Op.StartsWith:return Expression.call (handledmember, Startswithmethod, constant);
Case Op.EndsWith:return Expression.call (handledmember, Endswithmethod, constant);
return null;
private static binaryexpression getorexpression (parameterexpression param, filter filter1, filter filter2)
{Expression bin1 = getexpression (param, filter1);
Expression bin2 = getexpression (param, filter2);
Return expression.or (Bin1, bin2); private static Expression getexpression (parameterexpression param, IList<Filter> orfilters) {if (Orfilters.count = 0) return null;
Expression exp = null;
if (Orfilters.count = = 1) {exp = getexpression (param, orfilters[0]); else if (Orfilters.count = = 2) {exp = getorexpression (param, orfilters[0), Orfi
LTERS[1]); else {while (Orfilters.count > 0) {var
F1 = Orfilters[0];
var F2 = orfilters[1];
if (exp = null) {exp = getorexpression (param, orfilters[0], orfilters[1]); else {exp = expression.or (exp, getor
Expression (param, orfilters[0], orfilters[1));
} orfilters.remove (F1); Orfilters.reMove (F2); if (Orfilters.count = = 1) {exp = expression.or (exp, getexpression (param, Orfi
Lters[0]));
Orfilters.removeat (0);
}} return exp;
public static expression<func<t, bool>> getexpression<t> (filtercollection filters) { if (filters = null | | filters.
Count = 0) return null;
ParameterExpression param = Expression.parameter (typeof (T), "T");
Expression exp = null; if (filters.
Count = = 1) {exp = getexpression (param, filters[0]); else if (filters. Count = = 2) {exp = expression.andalso (getexpression (param, filters[0)), GetExpression (param,
FILTERS[1])); } else {while (filters).
Count > 0) {var f1 = filters[0];
var F2 = filters[1];
var f1andf2 = expression.andalso (getexpression (param, filters[0)), GetExpression (param, filters[1]);
if (exp = null) {exp = F1ANDF2;
else {exp = expression.andalso (exp, F1ANDF2); } filters.
Remove (F1); Filters.
Remove (F2); if (filters.
Count = = 1) {exp = expression.andalso (exp, getexpression (param, filters[0)); Filters.
RemoveAt (0);
}} return expression.lambda<func<t, bool>> (exp, param);
}
}
}
One more. Dynamic Build
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Linq.Expressions;
Using System.Reflection;
Using System.Text; namespace Jurassic.Sooil.Com {public static class Orderexpression {public static iorderedqueryable<t& Gt Orderby<t> (This iqueryable<t> source, string property) {return applyorder<t> (source
, property, "by"); The public static iorderedqueryable<t> orderbydescending<t> (this iqueryable<t> source, string prop
Erty) {return applyorder<t> (source, property, "OrderByDescending"); public static iorderedqueryable<t> thenby<t> (this iorderedqueryable<t> source, string property
) {return applyorder<t> (source, property, "ThenBy"); The public static iorderedqueryable<t> thenbydescending<t> (this iorderedqueryable<t> source, Strin
G property){return applyorder<t> (source, property, "thenbydescending"); Static iorderedqueryable<t> applyorder<t> (iqueryable<t> source, String, string method Name) {string[] props = property.
Split ('. ');
Type type = typeof (T);
ParameterExpression arg = expression.parameter (Type, "X");
Expression expr = arg;
foreach (string prop in props) {//Use Reflection (don't ComponentModel) to mirror LINQ 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 (). => 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;
}
}
}
This completes the dynamic construction of the LINQ query. It took a morning of work, but it was worth it, but the project manager knew it was a crying death.
No matter what, learn the hand is their own.