动态Linq的逻辑与和逻辑或的条件查询

最近在做一个数据检索的工作,对一个数据库中的宽表进行多个条件的检索。为了简单方便快捷的完成这个功能,我使用LINQ to SQL+ReportView的方式来完成。

首先需要做的是一个查询界面和写一个数据库查询方法。用户在输入框中输入多个指标,将根据指标的格式生成LINQ的Where语句。这个很容易实现,比如输入“2003 北京 人口”,那么就根据空格将这个字符串分成3个字符串,第一个字符串格式是年份,所以用表中的Year字段进行匹配,第二个字段是地区,所以再用表中的Location进行匹配,第三个是指标,那么就用指标进行匹配,具体的C#代码就是:

 public static List<Data2010> SearchData(string itemName)
{
using (DataClassesDataContext dc = new DataClassesDataContext())
{
var data = from d in dc.Data2010s
select d;
string[] items = itemName.Split(' ');

foreach (string item in items)
{
if (IsYear(item))
{
int year = Convert.ToInt32(item);
data = data.Where(d => d.Year ==year);
}
else if (IsLocation(item))
{
string location=item;
data = data.Where(d => d.Location == location);
}
else
{
string keyword=item;
data = data.Where(d => d.Indicator.Contains(keyword));
}
}

return data.ToList();
}
}

这个功能还简单,毕竟多个指标之间都是与的关系,但是接下来如果要实现或的关系,那么又该怎么办呢?这个让我伤了几天的脑筋。比如说如果要搜索北京、上海、重庆的2000年和2010年的人口,那么该怎么查呢,我定义了一个简单的语法,如果是或关系的指标,那么就在小括号中用空格隔开。那么查询字符串就变成了:

(北京 上海 重庆)(2000 2010) 人口

这样括号之间是与的关系,括号内的内容是或的关系。

但是真正的难点是如何用LINQ来实现动态的或查询。我第一想到的是Dynamic LINQ(具体参见:这里),这个在之前的项目中用过,特别强大,但是在这里用起来不是很方便,所以又想自己实现一套动态OR查询的方法,结果由于时间和能力有限,也没有做出来,最后终于找到一个很好的类库LinqKit,这个类库中有一个

PredicateBuilder类,可以非常简单的实现动态的逻辑或查询。到网站中下载该类库并添加到项目中,然后引用命名空间,将我们的搜索方法改为如下内容:

public static List<Data2010> SearchData(string itemName)
{
using (DataClassesDataContext dc = new DataClassesDataContext())
{
var data = from d in dc.Data2010s
select d;

Regex r = new Regex(@"\([^\)]*\)");
var ms = r.Matches(itemName);//匹配括号及其中的内容
if (ms.Count > 0)
{
foreach (Match m in ms)
{
string name = m.Value.Substring(1, m.Value.Length - 2);//去掉括号,只剩下之间的内容
string[] items = name.Split(' '); //各个Item之间是or的关系 空格区分

var predicate = PredicateBuilder.False<Data2010>();
foreach (string item in items)
{
predicate = predicate.Or(WhereCondition(item));//这里就是要用的动态逻辑或查询

//WhereCondition的定义是:Expression<Func<Data2010, bool>> WhereCondition(string item),就是根据item的格式判断该用哪个字段进行匹配

}
data = data.Where(predicate);//将最后的predicate传入Where函数,相当于是对括号之间进行逻辑与查询
}
itemName = r.Replace(itemName, " ");//把括号给替换掉,再对括号外的内容进行逻辑与查询
}

string[] items2 = itemName.Split(' ');

foreach (string item in items2)
{
data = data.Where(WhereCondition(item));
}

return data.ToList();
}
}

数据库查询函数已经完成,接下来就是要用ReportViewer来展现查询出来的结果绑定到报表中,具体代码如下:

private void BindData(string q)
{
var datas = DbOperation.SearchData(q);
this.ReportViewer1.LocalReport.DataSources.Clear();
this.ReportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource(
"DataSet1", datas));
this.ReportViewer1.DataBind();
}

这里的DataSet1就是对于rdlc报表的数据源,不能写错。

时间: 2024-08-03 20:16:51

动态Linq的逻辑与和逻辑或的条件查询的相关文章

C++短路求值(逻辑与、逻辑或)实例_C 语言

本文实例讲述了C++短路求值(逻辑与.逻辑或),分享给大家供大家参考.具体方法分析如下: 1.逻辑或的短路 首先看如下代码: #include <iostream> using namespace std; int main() { int a = 1; cout << "a = " << a <<endl; true || (a=0); cout << "a = " << a <<

基础才是重中之重~用好“逻辑与”和“逻辑或”,可以让你的程序更优美!

当进行"与"运算时,从左向右比较,出现一个为false时,立即退出,不会比较后台的,即使后面的有异常程序也不报错     当进行"或"运算时,从左向右比较,出现一个为true时,立即退出,不会比较后台的,即使后面的有异常程序也不报错 List<int> arr = null; if ( arr != null && arr.Count > 0) //其实arr.Count会报语法错误,但这里是正确的用法,先比较是否为null,如果为

Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)

为了提高开发者的易用性,Rafy 领域实体框架在很早开始就已经支持使用 Linq 语法来查询实体了.但是只支持了一些简单的.常用的条件查询,支持的力度很有限.特别是遇到对聚合对象的查询时,就不能再使用 Linq,而只能通过构造底层查询树的接口来完成了.由于开发者的聚合查询的需求越来越多,所以本周我们将这部分进行了增强. 接下来,本文将说明 Rafy 框架原来支持的 Linq 语法,以及最新加入的聚合查询支持及用法.   使用 Linq 查询的代码示例 public WarehouseList G

linq to entities-Linq to entities 多条件查询问题不知道有什么方法呢。

问题描述 Linq to entities 多条件查询问题不知道有什么方法呢. 在用实体类建模时候,用Linq根据条件查询数据表,对于多个条件的查询,原来是需要什么条件就写一个方法,在开发途中发现条件确实是太多= =, 便想用几个公用方法来包含这些条件,也就是条件为空的时候不执行这个where罢了 比如: if (FromUserId != """" && ToUserId != """") { var que

mybatis-Mybatis怎么实现同时动态多条件查询和对日期的范围查询

问题描述 Mybatis怎么实现同时动态多条件查询和对日期的范围查询 CREATE TABLE batchcon_info (batch_no varchar(50) NOT NULL DEFAULT '',file_name varchar(100) DEFAULT NULL,batch_state varchar(50) DEFAULT NULL,unit_no varchar(50) DEFAULT NULL,sum int(50) DEFAULT NULL,sum_money decim

Linq to Sql:N层应用中的查询(下): 根据条件进行动态查询

如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时 候,我们使用var来定义L2S查询,让编译器自动推断变量的具体类型 (IQueryable<匿名类型>), 并提供友好的智能提示:而且可以充分应用L2S的延迟加载特性,来进行动态查询.但如果我们希望将业 务逻辑放在一个独立的层中(譬如封装在远程的WCF应用中),又希望在逻辑层应用Linq to sql,则情况 就比较复杂了:由于我们只能使用var(IQueryable<匿

将商业逻辑与UI逻辑区分开

一般而言,我们需要设计我们的类如此以至于每一类做"一件事".当涉及用户接口代码时就更显得尤为重要,因为它很容易地封装"您要做什么"和"怎样显示它".这种有效的配合防止了代码的重复使用.更不用说它令人满意的从GUI中区分出我们的"事物逻辑".使用这种方法,我们可以不仅仅更容易地重复使用事物逻辑,它同样可以更容易地重复使用GUI. 其它的争议是"动作对象"存在的完成分离机器的多层次系统.动作主要的定位规则允许所

三层逻辑设计中逻辑层的输出问题

问题描述 逻辑层自表现层接受了用户的输入,经过逻辑层的处理以及从数据层取出来相应的数据,之后要输出给用户,那么应该如何做,直接newFrame()么?具体的说,逻辑层的类应该依赖表现层的类么?必须使用委托模式么? 解决方案 解决方案二:逻辑层的类不应该应该依赖表现层逻辑层是被表示层掉用数据显示处理应该由表示层处理

求 动态linq 的写法

问题描述 现在在写一个项目,其中有一个功能点,需要用到动态生成linq语句进行数据查询.具体需求如下:现有两张数据表,表A和表B.表A为数据表,表B为字典表,表结构如下:现在要检查表A中的各字段值是否在表B的字典值域内.frompin表Awherep.字段1这个where后面的字段值应该是动态从表B中读取的.然后检查这个字段是否在表B中.不知道我表述的是否清楚.在线等,就37分了,全送出去,大家别嫌少啊. 解决方案 解决方案二:没有这东西的写法.你要动态只能自己拼接SQL解决方案三://就四个字