c#--expression tree in LINQ dynamic Query __c#

Source: Internet
Author: User
Tags constant static class

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.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.