还是那句话,十年河东,十年河西,莫欺少年穷!

学无止境,精益求精...

今天探讨下如何构造动态的LINQ子查询

LINQ,相信大家都写过,很简单,下面以一个基本的范例说明下:

    namespace ConsoleMe
{
class Program
{
static List<Person> persons1 = new List<Person>();
static void Main(string[] args)
{
persons1.Add(new Person("张三", "男", , ));
persons1.Add(new Person("王成", "男", , ));
persons1.Add(new Person("李丽", "女", , ));
persons1.Add(new Person("何英", "女", , ));
persons1.Add(new Person("何大鸟", "男", , )); //LINQ 子查询
//查询姓 张、李、王 的人
var Query = from P in persons1
where P.Name.Contains("张") || P.Name.Contains("李") || P.Name.Contains("王")
select new PersonModel
{
Name = P.Name,
Sex = P.Sex,
Age = P.Age,
Money = P.Money
};
var list = new List<PersonModel>();
list = Query.ToList();
//
}
} public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public int Money { get; set; } public Person(string name, string sex, int age, int money)
{
Name = name;
Age = age;
Sex = sex;
Money = money;
}
} public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public int Money { get; set; } }
}

OK,上述的LINQ查询很简单

现在需求有所改变:查询姓 张 李 王 的男人

LINQ 变更如下:

                var Query = from P in persons1
where (P.Name.Contains("张") || P.Name.Contains("李") || P.Name.Contains("王"))&&P.Sex=="男"
select new PersonModel
{
Name = P.Name,
Sex = P.Sex,
Age = P.Age,
Money = P.Money
};

现在需求二次变更如下:查询姓 张 李 王 的男人 并且 年龄要大于20岁

LINQ 二次变更如下:

                var Query = from P in persons1
where (P.Name.Contains("张") || P.Name.Contains("李") || P.Name.Contains("王"))&&P.Sex=="男"&&P.Age>
select new PersonModel
{
Name = P.Name,
Sex = P.Sex,
Age = P.Age,
Money = P.Money
};

好了,如果您认为上述构建WHERE子句的方式就是动态构建的话,那么本篇博客就没有什么意义了!

那么什么样的方式才是真正的动态构建呢?

OK,咱们进入正题:

在此我提出一个简单需求如下:

我相信我的需求提出后,你用上述方式就写不出来了,我的需求如下:

请根据数组中包含的姓氏进行查询:

数组如下:

string[] xingList = new string[] { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈" };

在这里,有人可能会立马想到:分割数组,然后用十个 || 进行查询就行了!

我要强调的是:如果数组也是动态的呢?长度不定,包含的姓氏不定呢?

呵呵,想必写不出来了吧!

还好,LINQ也有自己的一套代码可以实现(如果LINQ实现不了,那么早就没人用LINQ了):

时间问题,就不多写了,直接粘贴代码了

详情可参考:http://www.cnblogs.com/blusehuang/archive/2007/07/13/816970.html

完整的方法是:

        public BaseResponse<IList<MessageModel>> GetMessageList(string Tags, string Alias, int pageSize, int pageIndex)
{
BaseResponse<IList<MessageModel>> response = new BaseResponse<IList<MessageModel>>();
var msg = base.unitOfWork.GetRepository<MSG_Message>().dbSet.Where(A=>!A.IsDeleted);//
var Query = from M in msg
select new MessageModel
{
CreatedTime = M.CreatedTime,
MessageContent = M.MessageContent,
MessageID = M.MessageID,
MessageTitle = M.MessageTitle,
MessageType = M.MessageType,
Tags=M.Tags,
Alias=M.Alias
};
ParameterExpression c = Expression.Parameter(typeof(MessageModel), "c");
Expression condition = Expression.Constant(false);
if (!string.IsNullOrEmpty(Tags))
{
string[] TagsAry = new string[] { };
TagsAry = Tags.Split(','); foreach (string s in TagsAry)
{
Expression con = Expression.Call(
Expression.Property(c, typeof(MessageModel).GetProperty("Tags")),
typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
Expression.Constant(s));
condition = Expression.Or(con, condition);
} }
if (!string.IsNullOrEmpty(Alias))
{
Expression con_Alias = Expression.Call(
Expression.Property(c, typeof(MessageModel).GetProperty("Alias")),
typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
Expression.Constant(Alias));
condition = Expression.Or(con_Alias, condition);
//
}
Expression<Func<MessageModel, bool>> end =
Expression.Lambda<Func<MessageModel, bool>>(condition, new ParameterExpression[] { c }); Query = Query.Where(end);
//
response.RecordsCount = Query.Count();
//
List<MessageModel> AllList = new List<MessageModel>();
List<MessageModel> AllList_R = new List<MessageModel>();
AllList_R = Query.ToList();
AllList = AllList_R.Where(A => A.Alias.Contains(Alias)).ToList();//加载所有Alias的
for (int i = ; i < AllList_R.Count; i++)
{
string[] TagsAry = new string[] { };
if (!string.IsNullOrEmpty(AllList_R[i].Tags))
{
TagsAry = AllList_R[i].Tags.Split(',');
bool bol = true;
foreach (var Cm in TagsAry)
{
if (!Tags.Contains(Cm))
{
bol = false;
break;
}
}
if (bol)
{
AllList.Add(AllList_R[i]);
}
}
}
AllList = AllList.OrderByDescending(A => A.CreatedTime).ToList();
if (pageIndex > && pageSize > )
{
AllList = AllList.Skip((pageIndex - ) * pageSize).Take(pageSize).ToList();
response.PagesCount = GetPagesCount(pageSize, response.RecordsCount); }
response.Data = AllList;
return response; }

需要指出的是:

Expression.Or(con, condition);  逻辑或运算
Expression.And(con, condition); 逻辑与运算

分析如下:

生成的LINQ子查询类似于:c=>c.Tags.Contains(s) || c=>c.Alias.Contains(Alias)....

@陈卧龙的博客

LINQ 如何动态创建 Where 子查询的更多相关文章

  1. LINQ之路 7:子查询、创建策略和数据转换

    在前面的系列中,我们已经讨论了LINQ简单查询的大部分特性,了解了LINQ的支持计术和语法形式.至此,我们应该可以创建出大部分相对简单的LINQ查询.在本篇中,除了对前面的知识做个简单的总结,还会介绍 ...

  2. C# linq对分组操作执行子查询

    本主题演示创建查询的两种不同方式,此查询将源数据排序成组,然后分别对每个组执行子查询. 每个示例中的基本方法是使用名为 newGroup 的"接续块"对源元素进行分组,然后针对 n ...

  3. Linq to SQL 语法整理(子查询 & in操作 & join )

    子查询 描述:查询订单数超过5的顾客信息 查询句法: var 子查询 = from c in ctx.Customers where (from o in ctx.Orders group o by ...

  4. LINQ之路 7:子查询、创建策略和数据转换(要点笔记)

    匿名类型 上面我们自己定义了类型TempProjectionItem来存放查询的结果.通过使用匿名类型,我们可以省去这种中间类型的定义,而由编译器来帮我们完成: select item.Origina ...

  5. 用jQuery绑定事件到动态创建的元素上

    jQuery最常用的一个功能就是对DOM的操作,与之相关的比如对事件的绑定和Ajax动态内容加载.当我们绑定事件到Ajax load回来的内容上或其他动态创建的元素上时会发现事件没响应,和你预想的结果 ...

  6. 动态创建Lambda表达式实现高级查询

    需求简介 最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表.其 中有一个功能是一个高级查询的需求,在查询条件方面大概有7.8个查询条件.需求就是如果一个条件 ...

  7. Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等)

    Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等) 子查询 描述:查询订单数超过5的顾客信息 查询句法: var 子查询 = from c i ...

  8. Linq专题之创建Linq查询表达式

    本节我们主要介绍一下如何创建查询集合类型,关系数据库类型,DataSet对象类型和XML类型的数据源的Linq查询表达式. 下面在实例代码ReadyCollectionData()函数创建了准备的数据 ...

  9. Linq To Sql 语法 子查询 & In & Join

    子查询 描述:查询订单数超过5的顾客信息 查询句法: var 子查询 =from cin ctx.Customers                    where                  ...

随机推荐

  1. Flutter 不一样的跨平台解决方案

    本文主要介绍Flutter相关的东西,包括Fuchsia.Dart.Flutter特性.安装以及整体架构等内容. 1. 简介 Flutter作为谷歌最近推出的跨平台开发框架,一经推出便吸引了不少注意. ...

  2. 怎样制作爽心的 dashboard ?

    在目前的大数据趋势中,数据的大屏可视化成为大家所推崇的一种互动展示模式.如果我们能够早一些了解和掌握这方面的技术,相信对我们的未来将会非常有帮助! 我们知道,通过报表工具实现大屏展示可以通过单张报表. ...

  3. Django的认证系统—auth模块

    Django的认证系统 auth模块的知识点总结: 1. 创建超级用户 python manage.py createsuperuser from django.contrib import auth ...

  4. 简述 Spring Cloud 是什么1

    很多同学都了解了Spring ,了解了 Spring Boot, 但对于 Spring Cloud 是什么还是比较懵逼的. 本文带你简单的了解下,什么是Spring Cloud. Spring Clo ...

  5. etcd raft如何实现Linearizable Read

    Linearizable Read通俗来讲,就是读请求需要读到最新的已经commit的数据,不会读到老数据. 对于使用raft协议来保证多副本强一致的系统中,读写请求都可以通过走一次raft协议来满足 ...

  6. 04-openldap客户端安装

    阅读视图 基础环境准备 关闭sssd及安装nslcd客户端 配置nslcd客户端 启动nslcd进程 客户端验证 ssh登录自动创建家目录 1. 基础环境准备 本文承接openldap服务端安装配置, ...

  7. Hybris 用户注册的时候何如添加指定的用户组

    主要逻辑:xxx.service.impl.ConsultantServiceImpl public class ConsultantServiceImpl extends DefaultCustom ...

  8. Linux结构目录

    linux结构目录 Linux中有一句话叫做:一切皆文件. 下面来了解一下这些文件. 首先看一下Linux根目录下结构: bin:存放二进制可执行文件,一般常用命令都存放在这里. boot:存放系统启 ...

  9. 多个Activity和Intent

    Intent是Android应用程序组件之一,在Android系统当中表示一种意图,Intent中包含了一组信息: 最重要的内容是action(动作)和data(数据) Component name ...

  10. Js 不支持函数的重载

    Js 不支持函数的重载,可以用相同的名字在同一作用区域,定义两个函数,而不会引起错误,但真正使用的是最后一个. Js 不会验证传递给函数的参数个数是否和函数定义的参数的个数相同,开发人员定义的函数都可 ...