Linq表達式淺析概述
本文向大家介紹Linq表達式,可能好多人還不了解Linq表達式,沒有關系,看完本文你肯定有不少收獲,希望本文能教會你更多東西。
當年,俺被誤導,說是linq怎么實現組合捏?因為linq是預編譯滴,沒有辦法想拼一個sql字符串出來,讓我糾結很久,但是,我覺得微軟的人應該比較厲害,所以我本著“有困難要上,沒有困難制造困難也要上”的原則,在還沒有熟悉LINQ TO ADO.NET的情況下,我覺得決定在最近的我自己獨立完成小項目里使用ASP.NET MVC + ADO.NET EF。一般的信息系統都有一個組合查詢的功能,我很快用jquery做了這樣一個功能。
這個表單將組合條件提交后臺,我先將它封裝成條件對象的數組:
- publicclassCondition
- {
- ///<summary>
- ///字段
- ///</summary>
- publicstringField{get;set;}
- ///<summary>
- ///表達式
- ///</summary>
- publicstringOperator{get;set;}
- ///<summary>
- ///值
- ///</summary>
- publicstringValue{get;set;}
- ///<summary>
- ///關系
- ///</summary>
- publicstringRelation{get;set;}
- ///<summary>
- ///
- ///</summary>
- ///<paramnameparamname="fileds"></param>
- ///<paramnameparamname="operators"></param>
- ///<paramnameparamname="values"></param>
- ///<paramnameparamname="relations"></param>
- ///<returns></returns>
- publicstaticCondition[]BuildConditions(string[]fileds,
string[]operators,string[]values,string[]relations)- {
- if(fileds==null||operators==null||values==null||relations==null)
- {
- returnnull;
- }
- Condition[]conditions=newCondition[fileds.Length];
- try
- {
- for(inti=0;i<conditions.Length;i++)
- {
- conditions[i]=newCondition()
- {
- Field=fileds[i],
- Operator=operators[i],
- Value=values[i],
- Relation=relations[i]
- };
- }
- }
- catch
- {
- returnnull;
- }
- returnconditions;
- }
- }
實際上,編譯器是把Linq表達式編譯成expression tree的形式,我只需要將條件對象數組轉換為expression tree就可以了。
我先將一個條件轉化為一個簡單的expression。
- privatestaticExpressionConditonToExpression(Conditioncondition,Expressionparameter)
- {
- Expressionexpr=null;
- Typetype=typeof(EDM_Resource);
- PropertyInfopi=type.GetProperty(condition.Field);
- ExpressionExpressionleft=Expression.Property(parameter,pi);
- objectvalue=Convert.ChangeType(condition.Value,pi.PropertyType);
- ExpressionExpressionright=Expression.Constant(value);
- switch(condition.Operator)
- {
- case"=":
- expr=Expression.Equal(left,right);
- break;
- case"<":
- expr=Expression.LessThan(left,right);
- break;
- case"<=":
- expr=Expression.LessThanOrEqual(left,right);
- break;
- case">":
- expr=Expression.GreaterThan(left,right);
- break;
- case">=":
- expr=Expression.GreaterThanOrEqual(left,right);
- break;
- }
- returnexpr;
- }
然后組合,變成一個Linq表達式,追加到where上。
- publicIList<EDM_Resource>FindByGroup(EDM_ResGroupresGroup,
Condition[]conditions,intfirst,intlimit,outintcount)- {
- using(ShengjingEDM2Entitiescontext=newShengjingEDM2Entities())
- {
- IQueryable<EDM_Resource>result=DoFindByGroup(resGroup,context);
- ParameterExpressionparameter=Expression.Parameter(typeof(EDM_Resource),"r");
- Expressionbody=null;
- if(conditions!=null&&conditions.Length>0)
- {
- body=ConditonToExpression(conditions[0],parameter);
- for(inti=1;i<conditions.Length;i++)
- {
- Expressionright=ConditonToExpression(conditions[i],parameter);
- body=conditions[i-1].Relation.ToUpper().Equals("AND")?
- Expression.And(body,right):
- Expression.Or(body,right);
- }
- }
- if(body!=null)
- {
- Expression<Func<EDM_Resource,bool>>expr=Expression.
Lambda<Func<EDM_Resource,bool>>(body,parameter);- resultresult=result.Where<EDM_Resource>(expr);
- }
- resultresult=result.OrderByDescending<EDM_Resource,int>(r=>r.ResourceID);
- count=result.Count<EDM_Resource>();
- returnresult
- .Skip<EDM_Resource>(first)
- .Take<EDM_Resource>(limit)
- .ToList<EDM_Resource>();
- }
- }
原來linq這么強大,這么爽,比拼where條件的方法優雅多了,開發效率也是提高不少,而且我發現性能也不錯,100萬級的數據通過索引和分頁查詢還算可以。
【編輯推薦】