如何解決用戶Linq自定義組合查詢
如何解決Linq自定義組合查詢?看起來似乎是個(gè)不太難的問題。但很多人仍然會(huì)卡在這里不知如何下手,今天我就用我的經(jīng)歷來給大家做一個(gè)例子。
當(dāng)年,俺被誤導(dǎo),說是怎么實(shí)現(xiàn)Linq自定義組合捏?因?yàn)長(zhǎng)inq是預(yù)編譯滴,沒有辦法想拼一個(gè)sql字符串出來,讓我糾結(jié)很久,但是,我覺得微軟的人應(yīng)該比較厲害,所以我本著“有困難要上,沒有困難制造困難也要上”的原則,在還沒有熟悉LINQ TO ADO.NET的情況下,我覺得決定在最近的我自己獨(dú)立完成小項(xiàng)目里使用ASP.NET MVC + ADO.NET EF。
一般的信息系統(tǒng)都有一個(gè)組合查詢的功能,我很快用jquery做了這樣一個(gè)功能。
這個(gè)表單將Linq自定義組合條件提交后臺(tái),我先將它封裝成條件對(duì)象的數(shù)組。
- ///
- /// 條件
- ///
- public class Condition
- {
- ///
- /// 字段
- ///
- public string Field { get; set; }
- ///
- /// 表達(dá)式
- ///
- public string Operator { get; set; }
- ///
- /// 值
- ///
- public string Value { get; set; }
- ///
- /// 關(guān)系
- ///
- public string Relation { get; set; }
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static Condition[] BuildConditions(string[] fileds,string[] operators,string[] values,string[] relations)
- {
- if (fileds == null || operators == null || values == null || relations == null)
- {
- return null;
- }
- Condition[] conditions = new Condition[fileds.Length];
- try
- {
- for (int i = 0; i < conditions.Length; i++)
- {
- conditions[i] = new Condition()
- {
- Field = fileds[i],
- Operator = operators[i],
- Value = values[i],
- Relation = relations[i]
- };
- }
- }
- catch
- {
- return null;
- }
- return conditions;
- }
- }
#p#
實(shí)際上,編譯器是把Linq自定義表達(dá)式編譯成expression tree的形式,我只需要將條件對(duì)象數(shù)組轉(zhuǎn)換為expression tree就可以了。
我先將一個(gè)條件轉(zhuǎn)化為一個(gè)簡(jiǎn)單的expression。
- ///
- ///
- ///
- ///
- ///
- ///
- private static Expression ConditonToExpression(Condition condition,Expression parameter)
- {
- Expression expr = null;
- Type type = typeof(EDM_Resource);
- PropertyInfo pi = type.GetProperty(condition.Field);
- Expression left = Expression.Property(parameter, pi);
- object value = Convert.ChangeType(condition.Value, pi.PropertyType);
- Expression right = 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;
- }
- return expr;
- }
#p#
然后組合,變成一個(gè)lamda表達(dá)式,追加到where上。
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IList
FindByGroup(EDM_ResGroup resGroup, Condition[] conditions, int first, int limit, out int count)- {
- using (ShengjingEDM2Entities context = new ShengjingEDM2Entities())
- {
- IQueryable
result = DoFindByGroup(resGroup, context); - ParameterExpression parameter = Expression.Parameter(typeof(EDM_Resource), "r");
- Expression body = null;
- if (conditions != null && conditions.Length > 0)
- {
- body = ConditonToExpression(conditions[0], parameter);
- for (int i = 1; i < conditions.Length; i++)
- {
- Expression right = ConditonToExpression(conditions[i],parameter);
- body = conditions[i - 1].Relation.ToUpper().Equals("AND") ?
- Expression.And(body, right) :
- Expression.Or(body, right);
- }
- }
- if (body != null)
- {
- Expression
bool>> expr = Expression.Lambda bool>>(body, parameter); - result = result.Where
(expr); - }
- result = result.OrderByDescending
int>(r => r.ResourceID); - count = result.Count
(); - return result
- .Skip
(first) - .Take
(limit) - .ToList
(); - }
- }
原來Linq自定義這么強(qiáng)大,這么爽,比拼where條件的方法優(yōu)雅多了,開發(fā)效率也是提高不少,而且我發(fā)現(xiàn)性能也不錯(cuò),100萬級(jí)的數(shù)據(jù)通過索引和分頁查詢還算可以。
【編輯推薦】






