理想中的SQL语句条件拼接方式_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 理想中的SQL语句条件拼接方式

理想中的SQL语句条件拼接方式

 2013/10/31 23:12:01  冲动  博客园  我要评论(0)
  • 摘要:背景Orm用过一些,但处理增删改上面做的都不错。但是查询上跟我想要的效果总是差了一点。我想要的效果则是这样,基于某种命名规则进行传参,后台解析器知道命名规则即可知道它要查询什么样的数据。谈谈我之前的做法,比如说,页面将查询条件存入对象,序列化后后传递给控制器,此时控制器将其反序列化成Json,数据类型使用Dictionary<string,object>。里面存储的Key目前是这样的格式:BeginTime,EndTime,Age,LikeAddress,NullTel
  • 标签:方式 SQL SQL语句

背景

  Orm用过一些,但处理增删改上面做的都不错。但是查询上跟我想要的效果总是差了一点。我想要的效果则是这样,基于某种命名规则进行传参,后台解析器知道命名规则即可知道它要查询什么样的数据。

  谈谈我之前的做法,比如说,页面将查询条件存入对象,序列化后后传递给控制器,此时控制器将其反序列化成Json,数据类型使用Dictionary<string,object>。里面存储的Key目前是这样的格式: BeginTime, EndTime, Age, LikeAddress , NullTel , UnLikeMM , 其中 Begin End Like UnLike Null 等是自定义的命名规则,告诉后台我需要查询的数据类型,具体的含义看前缀大致即可知道。如传入BeginTime=2013-10-31 21:55:47,希望得到时间大于这个值的数。

  当时后台则是尝试去判断每一个值,如使用 Dictionary.TryGetValue("BeginTime",out obj) , 来进行条件的传值判断。这个地方还存在一个类型问题,时间到了后台变成了时间字符串,而不是DateTime类型。此处则需要强制转换。也正式因为这些原因,代码写的不大工整,尽管做了一些封装,稍微简洁点,但还不是我要的效果。

  以此为主题,写了一个初步的实现,希望各位朋友能给出部分建议,如果有类似的成熟的框架,能让我在后台定义个SQL之后,前端只要传入规定的命名字段,即可完成查询,这样是再好不过了。

测试效果

            var strSql = "select * from Users where ";
            var dic = new Dictionary<string, object>();
            dic["BeginAge"] = "18";//Age>=18
            dic["EndAge"] = 80;//Age<=80
            dic["LikeName"] = "";//Name包含'玲'
            dic["IsGirl"] = "true";//IsGirl = true 
            dic["BeginLoginTime"] = DateTime.Now.AddDays(-7);//LoginTime >= 七天前
            dic["EndLoginTime"] = DateTime.Now.ToString();//LoginTime <= 今天
            //部分类型若不正确,则需要手动映射
            SqlMapper mapper = new SqlMapper(dic);
            mapper.LoadTypeMapper<DateTime>("LoginTime");
            mapper.LoadTypeMapper<int>("Age");
            mapper.LoadTypeMapper<bool>("IsGirl");
            //看看生成的条件语句
            var where = mapper.Where();
            Console.WriteLine("{0} {1}", strSql, where);
            Console.WriteLine();

  

  目前的效果则如图,得到对应的SQL语句,并且将数据类型转换正确。

  我们在看看复杂的查询。

            strSql = "select * from Table1 t1 inner join Table2 t2 on t1.ID=t2.Table1ID where ";
            dic["t1.UserName"] = "admin";//UserName='admin'
            dic["t1.BeginAge"] = 18;//Age>=18
            dic["t1.EndAge"] = "80";//Age<=80
            dic["t1.NullSex"] = "false";//Sex is not null
            dic["t1.NullNice"] = "true";//Nice is true
            dic["t2.LikeHomeName"] = "中国";//HomeName like '%中国%'
            dic["t2.UnLikeAddress"] = "郊区";//Address not like '%郊区%'
            dic["t2.BeginCreateTime"] = DateTime.Now.ToString();//CreateTime >= DateTime.Now
            mapper = new SqlMapper(dic);
            mapper.LoadTypeMapper<DateTime>("CreateTime");
            mapper.LoadTypeMapper<int>("Age");
            mapper.LoadTypeMapper<bool>("Sex");
            where = mapper.Where();
            Console.WriteLine("{0} {1}", strSql, where);
            Console.WriteLine();
            //看看格式化后的Dictionary
            foreach (var e in dic)
            {
                Console.WriteLine("{0}:{1}      {2}", e.Key, e.Value, e.Value.GetType());
            }

    

    我想要的效果,大致就是这样,由于是测试代码,所以直接构造了Dictionary,并且写入了对应的数据(类型有正确有错误)。

 

    实现方式很简单,则是遍历Dictionary,根据命名规则定义的前缀,来拼接SQL语句,并且检测当前类型,如果是string类型,则需要和映射的类型匹配一下,不相同,则将string类型转换成Mapper中映射的类型。

    最后在重申一下我想达到的目的,后台定义SQL语句,如Select ....,方法接收Dictionary参数,解析后传递给ado或者orm去执行,如此一来,前端想查询什么样的数据,只需要定义条件就好了。

 

  测试代码下载

    

发表评论
用户名: 匿名