如何解决用户Linq自定义组合查询
创始人
2024-06-06 10:11:07
0

如何解决Linq自定义组合查询?看起来似乎是个不太难的问题。但很多人仍然会卡在这里不知如何下手,今天我就用我的经历来给大家做一个例子。

当年,俺被误导,说是怎么实现Linq自定义组合捏?因为Linq是预编译滴,没有办法想拼一个sql字符串出来,让我纠结很久,但是,我觉得微软的人应该比较厉害,所以我本着“有困难要上,没有困难制造困难也要上”的原则,在还没有熟悉LINQ TO ADO.NET的情况下,我觉得决定在最近的我自己独立完成小项目里使用ASP.NET MVC + ADO.NET EF。

一般的信息系统都有一个组合查询的功能,我很快用jquery做了这样一个功能。

 

这个表单将Linq自定义组合条件提交后台,我先将它封装成条件对象的数组。

  1. ///   
  2. /// 条件  
  3. /// 
  4.  
  5. public class Condition  
  6. {  
  7.     ///   
  8.     /// 字段  
  9.     /// 
  10.  
  11.     public string Field { getset; }  
  12.     ///   
  13.     /// 表达式  
  14.     /// 
  15.  
  16.     public string Operator { getset; }  
  17.     ///   
  18.     /// 值  
  19.     /// 
  20.  
  21.     public string Value { getset; }  
  22.     ///   
  23.     /// 关系  
  24.     /// 
  25.  
  26.     public string Relation { getset; }  
  27.  
  28.     ///   
  29.     ///   
  30.     /// 
  31.  
  32.     ///   
  33.     ///   
  34.     ///   
  35.     ///   
  36.     ///   
  37.     public static Condition[] BuildConditions(string[] fileds,string[] operators,string[] values,string[] relations)  
  38.     {  
  39.         if (fileds == null || operators == null || values == null || relations == null)  
  40.         {  
  41.             return null;  
  42.         }  
  43.         Condition[] conditions = new Condition[fileds.Length];  
  44.         try 
  45.         {  
  46.             for (int i = 0; i < conditions.Length; i++)  
  47.             {  
  48.                 conditions[i] = new Condition()  
  49.                 {  
  50.                     Field = fileds[i],  
  51.                     Operator = operators[i],  
  52.                     Value = values[i],  
  53.                     Relation = relations[i]  
  54.                 };  
  55.             }  
  56.         }  
  57.         catch 
  58.         {  
  59.             return null;  
  60.         }  
  61.         return conditions;  
  62.     }  

#p#

实际上,编译器是把Linq自定义表达式编译成expression tree的形式,我只需要将条件对象数组转换为expression tree就可以了。

我先将一个条件转化为一个简单的expression。

  1. ///   
  2. ///   
  3. /// 
  4.  
  5. ///   
  6. ///   
  7. ///   
  8. private static Expression ConditonToExpression(Condition condition,Expression parameter)  
  9. {  
  10.     Expression expr = null;  
  11.     Type type = typeof(EDM_Resource);  
  12.  
  13.     PropertyInfo pi = type.GetProperty(condition.Field);  
  14.     Expression left = Expression.Property(parameter, pi);  
  15.  
  16.     object value = Convert.ChangeType(condition.Value, pi.PropertyType);  
  17.     Expression right = Expression.Constant(value);  
  18.     switch (condition.Operator)  
  19.     {  
  20.         case "=":  
  21.             expr = Expression.Equal(left, right);  
  22.             break;  
  23.         case "<":  
  24.             expr = Expression.LessThan(left, right);  
  25.             break;  
  26.         case "<=":  
  27.             expr = Expression.LessThanOrEqual(left, right);  
  28.             break;  
  29.         case ">":  
  30.             expr = Expression.GreaterThan(left, right);  
  31.             break;  
  32.         case ">=":  
  33.             expr = Expression.GreaterThanOrEqual(left, right);  
  34.             break;  
  35.     }  
  36.     return expr;  

#p#

然后组合,变成一个lamda表达式,追加到where上。

  1. ///   
  2. ///   
  3. /// 
  4.  
  5. ///   
  6. ///   
  7. ///   
  8. ///   
  9. ///   
  10. ///   
  11. public IList FindByGroup(EDM_ResGroup resGroup, Condition[] conditions, int first, int limit, out int count)  
  12. {  
  13.     using (ShengjingEDM2Entities context = new ShengjingEDM2Entities())  
  14.     {  
  15.         IQueryable result = DoFindByGroup(resGroup, context);  
  16.         ParameterExpression parameter = Expression.Parameter(typeof(EDM_Resource), "r");  
  17.         Expression body = null;  
  18.  
  19.         if (conditions != null && conditions.Length > 0)  
  20.         {  
  21.             body = ConditonToExpression(conditions[0], parameter);  
  22.             for (int i = 1; i < conditions.Length; i++)  
  23.             {  
  24.                 Expression right = ConditonToExpression(conditions[i],parameter);  
  25.                 body = conditions[i - 1].Relation.ToUpper().Equals("AND") ?  
  26.                     Expression.And(body, right) :  
  27.                     Expression.Or(body, right);  
  28.             }  
  29.         }  
  30.  
  31.         if (body != null)  
  32.         {  
  33.             Expressionbool>> expr = Expression.Lambdabool>>(body, parameter);  
  34.             result = result.Where(expr);  
  35.         }  
  36.         result = result.OrderByDescendingint>(r => r.ResourceID);  
  37.         count = result.Count();  
  38.         return result  
  39.             .Skip(first)  
  40.             .Take(limit)  
  41.             .ToList();  
  42.     }  

原来Linq自定义这么强大,这么爽,比拼where条件的方法优雅多了,开发效率也是提高不少,而且我发现性能也不错,100万级的数据通过索引和分页查询还算可以。

【编辑推荐】

  1. LINQ——语言级集成查询入门指南
  2. LINQ查询的目的与实现手段
  3. 实例二:绑定到LINQ查询的结果
  4. LINQ查询表达式深入剖析
  5. LINQ的演变及其对C#设计的影响

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...