"Reprint" C # Advanced Series--Dynamic Lamada

Source: Internet
Author: User

Foreword: In the DDD series, we encapsulate the general method of transmitting Lamada expression in the background storage, similar to this:

Public virtual iqueryable<tentity> Find (expression<func<tentity, Bool>> Express)        {            Func <tentity, bool> Lamada = Express.compile ();            Return unitofwork.context.set<tentity> (). Where (Lamada). Asqueryable<tentity> ();        }

Through the front end of the Lamada expression, put directly into the Where condition query. So the question is, how do we get the front end into Lamada? Of course, someone said, this does not preach ah, the front-end directly. Find (x=>x.name== "abc") It's good to write like this. Indeed, if there is only one condition for the front-end condition, you can do so simply, but in the actual development process, we often need to pass multiple parameters, and. Find (x=>x.name== "abc") This method is also not conducive to the encapsulation of methods. So, our magical dynamic Lamada was born.

One, again talk about Lamada expression 1, anonymous delegate

Before introducing a delegate, we introduced a special kind of anonymous delegate, such as:

    Class program    {        private delegate void SayHello (string name);        static void Main (string[] args)        {            Say ("Zhang San", Delegate (string name)            {                Console.WriteLine ("Hello," + name);            });            Say ("Zhangsan", delegate (string name)            {                Console.WriteLine ("Hello," + name);            });        static void Say (String Name,sayhello dtest)        {            dtest (name);        }      }

That is, instead of defining a specific delegate method to correspond to SayHello (string name), the direct delegate (string name) {} defines an anonymous delegate to execute, which reduces the code that defines the specific method in some way.

2. Evolutionary history of Lamada expression

Knowing the concept of anonymous delegates, let's take a look at the extension methods that we often use in LINQ, where, select, and so on. Let's take a look at the general usage:

var lsttest = new list<string> ();
//....... Business logic var lstres = lsttest.where (x = X.contains ("_"));

Let's decompose x = X.contains ("_") in Where.

Primary evolution (most primitive anonymous delegate form):
func<string, bool> Ofunc = Delegate (string x) {return X.contains ("_");}; Lstres = Lsttest.where (Ofunc);
Advanced Evolution (Type Lamada, but also anonymous Delegate shadow):
func<string, bool> ofunc = (string x) + = {return X.contains ("_");}; Lstres = Lsttest.where (Ofunc);
Ultimate Evolution (completely lamada)
func<string, bool> ofunc = x = X.contains ("_"); Lstres = Lsttest.where (Ofunc);

There is no very strong, is not the same. In fact, such a look at Lamada is the abbreviated form of anonymous delegation. x = X.contains ("_") the expression to the left represents the string type variable inside func, and X.contains ("_") represents the return value of type bool. With this evolutionary history, programmers no longer have to worry about the interviewer asking me Lamada what's going on.

Second, dynamic Lamada

Rather than dynamic lamada, a more rigorous point should be called dynamic expression, because the concatenation of Lamada expression is basically a class and method of expression. Bloggers habits, for the moment call it dynamic Lamada bar. Don't say much nonsense, just eat some chestnuts.

public class Dto_order    {public        string to_order_id {get; set;}        public string Order_no {get; set;}        public string Order_name {get; set;}        public int Order_status {get;set;}    }
    static void Main () {//1. Defines Lamada parameters, such as "x=>" parameterexpression m_parameter = Ex, which we write frequently Pression.            Parameter (typeof (Dto_order), "X"); 2. Define the attribute members to use Lamada (for example, we want to filter the Order_no property of the Dto_order object here) memberexpression member = Expression.propertyorfield (m_            Parameter, "Order_no"); 3. Define the action of the filter (is greater than, equal to, less than, like, etc.) Expression Expres = expression.equal (Member, Expression.constant ("AAAA", member.            Type)); 4. Convert expression to Lamada expression Expression<func<dto_order, bool>> Exprelamada = expression.lambda<func<            Dto_order, Bool>> (Expres, M_parameter);            var lstres = new list<dto_order> ();                for (var i = 0; i < i++) {var omodel = new Dto_order (); Omodel.order_no = i% 2 = = 0?                "AAAA": "BBBB";            Lstres.add (Omodel); //5. Convert expression expression to func delegate, used in where parameter var Lamada = Exprelamada.compilE (); Lstres = Lstres.where (Lamada).    ToList (); }

The above constructs a query list<dto_order> object inside the Order_no property equals aaaa lamada expression. Let's see how it works:

is not already getting the expression we want! There is no very simple ...

Third, the use of dynamic Lamada

See here someone is depressed, in order to get x=>x.order_no== "aaaa" This expression, you around so big circle, what kind of dick use? Direct Lstres=lstres.where (x=>x.order_no== "AAAA"); you have to complicate the simple question in order to get it done. In fact, there are certain programming experience of friends must know, generally our front-end transmission of query parameters will certainly not only one, when the need to query multiple parameters we need to construct a unified Lamada pass to the background; Of course you can also say that I pass multiple parameters to the background, Then use the IQueryable interface in the background to filter. Sure, it works, but don't forget we encapsulate find (Expression exp ...). Meaning, is not to simplify the method, from this point of view, the construction of dynamic Lamada is very necessary.

1. General Lamada Expression Class

The blogger encapsulates a dynamic Lamada class with a simple operation (greater than, equal to, less than, like, etc.).

public class lamadaextention<dto> where Dto:new () {private list<expression> m_lstexpression = null        ;        Private parameterexpression m_parameter = null;            Public lamadaextention () {m_lstexpression = new list<expression> ();        M_parameter = Expression.parameter (typeof (Dto), "X"); }
     Constructs an expression that is stored in the M_lstexpression collection inside the public void getexpression (String strPropertyName, Object strvalue, Expressionty PE expresstype) {Expression expres = null; Memberexpression member = Expression.propertyorfield (M_parameter, strPropertyName); if (Expresstype = = expressiontype.contains) {Expres = Expression.call (Member, typeof (String). GetMethod ("Contains"), Expression.constant (strvalue)); } else if (Expresstype = = expressiontype.equal) {Expres = expression.equal (Member, E Xpression. Constant (strvalue, member. Type)); } else if (Expresstype = = Expressiontype.lessthan) {expres = Expression.lessthan (mem ber, Expression.constant (strvalue, member. Type)); } else if (Expresstype = = expressiontype.lessthanorequal) {expres = Expression.lesst Hanorequal (Member, Expression.constant (strValue, member. Type)); } else if (Expresstype = = Expressiontype.greaterthan) {expres = Expression.greaterth An (Member, Expression.constant (strvalue, member. Type)); } else if (Expresstype = = expressiontype.greaterthanorequal) {expres = expression.gr Eaterthanorequal (Member, Expression.constant (strvalue, member. Type)); }//return Expres; M_lstexpression.add (Expres); }//Expression for the or condition public void getexpression (String strpropertyname, list<object> lstvalue) { Expression expres = null; Memberexpression member = Expression.propertyorfield (M_parameter, strPropertyName); foreach (Var ovalue in Lstvalue) {if (Expres = = null) {Expre s = expression.equal (member, Expression.constant (Ovalue, member. Type)); } else {expres = expression.or (Expres, Expression.equal (member, Expression.constant (Ovalue, member). Type)); }} m_lstexpression.add (Expres); }
Get expression object public expression<func<dto of Lamada expressions, bool>> Getlambda () {Expressio n whereexpr = null; foreach (Var expr in this.m_lstexpression) {if (whereexpr = = null) whereexpr = expr; else whereexpr = Expression.and (whereexpr, expr); } if (whereexpr = = null) return null; Return expression.lambda<func<dto, boolean>> (whereexpr, M_parameter); } }
Enumeration public enum Expressiontype {contains,//like equal,//equals lessthan,//less than lessth used to differentiate operations anorequal,//less than or equal to greaterthan,//greater than greaterthanorequal//greater than equals}
2. Usage Scenarios

Bo Master project has a certain page, query conditions are very many, need to pass to the background a lot of parameters. Take a look at the page first:

Look at the background Web API code

public object Get (int limit, int offset, string strbodyno, String Strvin, String Strorderno, String Strengincode, String Strorderstatus, String Strtranscode, String Strvms, String Strcarcode, String strimportst            Artdate, String strimportenddate, String strsendstartdate, String strsendenddate) {//1. Define object, incoming generic            var olamadaextention = new lamadaextention<dto_to_order> (); 2. Construct the Lamada expression if (!string) in turn. IsNullOrEmpty (Strbodyno)) {olamadaextention.getexpression ("Body_no", Strbodyno, Expressiontype.            Contains); } if (!string.             IsNullOrEmpty (Strvin)) {olamadaextention.getexpression ("VIN", Strvin, Expressiontype.contains); } if (!string. IsNullOrEmpty (Strorderno)) {olamadaextention.getexpression ("Order_no", Strorderno, Expressionty Pe.            Contains); } if (!string. IsnullorempTy (Strengincode)) {olamadaextention.getexpression ("Engin_code", Strengincode, expressiontype.co            Ntains); } if (!string.                    IsNullOrEmpty (Strorderstatus)) {if (Strorderstatus.contains (",")) { var lstvalue = Strorderstatus.split (",". ToCharArray (), stringsplitoptions.removeemptyentries).                    ToList ();                    var lstobj = new list<object> ();                    Lstvalue.foreach (x = {Lstobj.add (convert.toint16 (x));                    });                Olamadaextention.getexpression ("Order_status", lstobj); } else {olamadaextention.getexpression ("Order_status", Convert.ToInt16 (s                Trorderstatus), expressiontype.equal); }} if (!string. IsNullOrEmpty (Strtranscode)) {olamadaextention.getexpression ("Trans_code", Strtranscode, expressiontype.contains); } if (!string. IsNullOrEmpty (Strvms)) {olamadaextention.getexpression ("Vms_no", Strvms, Expressiontype.contain            s); } if (!string. IsNullOrEmpty (Strcarcode)) {olamadaextention.getexpression ("tm_model_material_id", Strcarcode,            Expressiontype.contains); } if (!string. IsNullOrEmpty (strimportstartdate)) {olamadaextention.getexpression ("create_date", Convert.todat            ETime (strimportstartdate), expressiontype.greaterthanorequal); } if (!string. IsNullOrEmpty (strimportenddate)) {olamadaextention.getexpression ("create_date", Convert.todatet            IME (strimportenddate), expressiontype.lessthanorequal); } if (!string. IsNullOrEmpty (strsendstartdate)) {olamadaextention.getexpression ("offline_date_act", Convert.To DateTime (strsendstartdate), ExpreSsiontype.greaterthanorequal); } if (!string. IsNullOrEmpty (strsendenddate)) {olamadaextention.getexpression ("offline_date_act", Convert.toda            Tetime (strsendenddate), expressiontype.lessthanorequal);            }//3. Get the Lamada expression you want expressions var Lamada = Olamadaextention.getlambda (); var lstres = Ordermanager.find (Lamada).                        ToList ();        4. Get bootstrap table required var ores = new Pagerowdata ();        return ores;; }

The Find method inside the warehouse base class:

Public virtual iqueryable<tentity> Find (expression<func<tentity, Bool>> Express)        {            Func <tentity, bool> Lamada = Express.compile ();            Return unitofwork.context.set<tentity> (). Where (Lamada). Asqueryable<tentity> ();        }
Iv. Summary

At this point, the so-called dynamic Lamada is finished. If you've used it before, please smile, but if you don't use it, it's good to learn something new. Please do not laugh at bloggers confused definition, called dynamic Lamada is very good. Of course you can call dynamic expression, dynamic LINQ is OK, no matter what it is called, the right use is the kingly way.

Reprinted from: http://www.cnblogs.com/landeanfen/p/4923216.html

"Reprint" C # Advanced Series--Dynamic Lamada

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.