如何解决用户Linq自定义组合查询

开发 后端
本文详细讲解了Linq自定义组合查询的实现方法,希望能给大家带来一些启示。

如何解决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#设计的影响
责任编辑:林琳 来源: Javaeye
相关推荐

2009-09-07 22:00:15

LINQ自定义

2009-09-13 18:58:07

自定义LINQ提供器

2009-09-07 22:29:04

LINQ组合查询

2015-02-12 15:38:26

微信SDK

2021-06-17 06:52:37

C#自定义异常

2018-07-06 15:58:34

SpringSchemaJava

2013-06-27 11:10:01

iOS开发自定义UISlider

2009-09-09 13:39:05

Linq用户定义函数

2010-10-20 16:07:48

SQL用户自定义角色

2009-08-03 13:39:46

C#自定义用户控件

2009-09-15 17:45:34

Linq多条件

2021-07-16 11:00:40

Django用户模型Python

2011-03-02 10:24:23

DashboardAndroid用户界面设计模板

2010-02-07 14:02:16

Android 界面

2015-02-12 15:33:43

微信SDK

2021-07-15 16:41:21

Swift查询函数

2009-09-07 22:54:03

Linq组合查询

2011-07-04 14:08:02

C++

2009-09-03 13:34:03

.NET自定义控件

2023-01-03 07:40:27

自定义滑块组件
点赞
收藏

51CTO技术栈公众号