OQL如何支持CASE WHEN?

今天,一个朋友问我,OQL可否支持CASE WHEN语句?他给的示例SQL如下:

select HName,case when IsEnable=1 then '启用' else '停用' from tb_User

OQL是SOD框架ORM查询语言,它类似Linq,但是它诞生的历史比Linq早,并且更加接近SQL语法。所以,对SOD框架而言,对应ORM如何支持CASE WHEN,就等于是问OQL如何支持CASE WHEN了。

这个问题已经不止这一个朋友来问我了,我想了下,还是把这个问题的解决写一篇博客,给大家一种新的解决方案。
注意“新的方案”这个提法,我是不打算让OQL支持CASE WHEN这个特性的,为何要这样做呢?

  1. OQL只解决 80%的普通查询,其它复杂的查询,应该依托于其它技术,否则会增加OQL的复杂性;
  2. 复杂的查询,可以借助于SOD框架的SQL-MAP技术,将SQL语句写在SqlMap.config文件中;
  3. 可以采用数据库视图或者表的计算列,但有些数据库可能不支持计算列;

前面3种原因,第2,3条方法也可以看做是此问题的解决方案,但是它们都需要增加更多的工作量,如果OQL能够直接支持还是更方便些,所以,我今天在这里给大家第4种解决方案:

实体类的计算属性

废话不多说,先直接看代码:

public class User:EntityBase
{
public User()
{
TableName="tb_User";
} public string HName{
get{return getProperty<string>("HName");}
set{setProperty<string>("HName",value,);}
} public bool IsEnable{
get{return getProperty<bool>("IsEnable");}
set{setProperty<bool>("IsEnable",value);}
} public string IsEnableDescrition
{
get{
return IsEnable?"启用":"停用"
}
} }

在这里,HName,IsEnable 这样的属性,SOD框架称为“持久化属性”,因为它MAP了Tb_User表的字段IsEnable ,该字段称为“持久化属性字段”。

持久化属性的get,set方法采用了SOD实体类特殊的方法 setProperty,getProperty 构造,所以属性IsEnableDescription 它不是持久化属性,但是它利用了IsEnable这个持久化属性,对持久化属性进行“计算”,因此,我们这里称呼这样的属性为实体类的“计算属性”。

大家看看,这个“计算属性”是不是很好的起到了 SQL的CASE WHEN效果?

只要忘记了数据库,不要遇到问题就去想如何用SQL语句解决,是不是思路豁然开朗?

使用“计算属性”来支持CASE WHEN效果

前面说过,实体类的“计算属性”本质上不是一个“持久化属性”,它是对持久化属性的计算处理,原理上非常类似SQLServer表上面的计算列。
因此,在SOD框架上使用“计算属性”,有一个必须注意的原则:“计算属性”不可以出现在OQL语句中。

具体举例来说,应该像下面的样子来使用包含计算列的实体类:

User user=new User(){ HName="张三"};
var q=OQL.From(user)
.Select(user.HName,user.IsEnable)
.Where(user.HName)
.END; User user2= EntityQuery<User>.QueryObject(q);
string isEnableDesction =user2.isEnableDesction;

使用“ViewModel”来支持CASE WHEN效果

如果再仔细看看开篇的这个SQL语句,我们发现这种写法常常跟我们的界面查询有关,也就是这个查询要将原来的结果进行一下加工,以方便界面元素使用。对应这种需求,我们通常想到的办法是写一个ViewModel来定制这个查询结果。实际上,前面那个SOD实体类就是一种ViewModel,但它是基于实体类上的ViewModel,之外,SOD也支持直接将查询结果映射到ViewModel。

因此,前面的实体类需要改写成下面这个样子:

public class User:EntityBase
{
public User()
{
TableName="tb_User";
} public string HName{
get{return getProperty<string>("HName");}
set{setProperty<string>("HName",value,);}
} public bool IsEnable{
get{return getProperty<bool>("IsEnable");}
set{setProperty<bool>("IsEnable",value);}
} }

这里去掉了前面的“计算列属性”,它将用一个匿名类型的属性来代替:

User user=new User(){ HName="张三"};
var q=OQL.From(user)
.Select()
.Where(user.HName)
.END; PWMIS.DataProvider.Data.AdoHelper db = PWMIS.DataProvider.Adapter.MyDB.GetDBHelper();
EntityContainer ec = new EntityContainer(q, db);
var list = ec.MapToList()(()=> return new
{
HName = user.HName,
IsEnableDescription =user.IsEnable?"启用":"停用"
});

这里的匿名类型中包含了 IsEnableDescription 一个属性,同时我们的OQL查询也不再需要在Select里面指定查询的属性,而是推迟到MapToList方法里面。

上面这种查询方式,同样支持了我们标题的需求,可见,SOD对一个查询问题,往往能够提供多种解决方案,“条条道路通罗马”,这正是SOD的设计谏言。

---------------分界线--------------------------------------------------------------------------------

有关上面SOD框架查询使用的入门介绍,大家可以参考《.NET ORM 的 “SOD蜜”--零基础入门篇 》

感谢大家对SOD框架一直以来的支持,更多信息,请参考 PDF.NET SOD 开源框架红包派送活动 && 新手快速入门指引

开源项目需要大家更多的支持,SOD开源项目网站:http://pwmis.codeplex.com

如何用ORM支持SQL语句的CASE WHEN?的更多相关文章

  1. SQL语句中case函数

    case函数,严格的意义上来讲case函数已经试流程控制语句了,不是简单意义上的函数,不过为了方便,很多人将case函数称为流程控制函数. case函数的一般有两种用法:1.case expressi ...

  2. sql 语句之 case

    case语句语法: --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END --Case搜索函数 CASE WHEN ...

  3. sql语句判断 case when用法

    sql语句判断方法之一 selectcase when t.bk1='on' then 1else 0 end  as 基础 ,case when t.bk2='on' then 1else 0 en ...

  4. 【Swift 4.0】扩展 WCDB 支持 SQL 语句

    前言 入坑 wcdb 有两个月了,整体来说还是很不错的,具体优点可以参考文档说明,由于官方明确说明不支持 SQL 只好自己写一个扩展支持一下了

  5. Oracle的sql语句中case关键字的用法 & 单双引号的使用

    关于sql中单引号和双引号的使用,来一点说明: 1. 查询列的别名如果含有汉字或者特殊字符(如以'_'开头),需要用双引号引起来.而且只能用双引号,单引号是不可以的. 2. 如果想让某列返回固定的值, ...

  6. 让EF支持sql语句

    BaseDal类: public class BaseDal : IDisposable { #region 事件 internal Func<bool> DBCommitting; in ...

  7. sql语句:CASE WHEN END 的用法

    select b,c, CASE a ' ' ' end from test1

  8. 条件分支SQL语句<一> Case When

    SELECT END ) AS MoneyIn, END ) AS MoneyOut, END ) AS BetMoney, END ) AS PctMoney, END ) AS WinMoney, ...

  9. SQL语句中case,when,then的用法

    用法如下bai: 复制代码 SELECT s.s_id, s.s_name, s.s_sex, CASE WHENs.s_sex='1'THEN'男' WHENs.s_sex='2'THEN'女' E ...

随机推荐

  1. 微信小程序产品定位及功能介绍

    产品定位及功能介绍 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 小程序注册 注册小程序帐号 在微信公众平台官网首页(mp.weixin.qq ...

  2. Android开发学习之路-Android Studio真神器!

    放假之后电脑配置升级就开始用Android Studio(下面简称AS)了,那个酸爽真的不是一般的啊,这里开一篇博客来记录下AS里面各种酷炫的功能,有更好玩的,大家不要吝啬,评论告诉我吧! 最近And ...

  3. 移动开发--Hybrid和Native混合开发-->HybridApp 、NativeApp、WebApp

    1.1.     APP三种开发模式 智能手机之普及不用多说,手机APP渗投到各个行业:电商(淘宝.京东等).金融(各手机行业.P2P借贷等).医疗(智慧医疗).交通(滴滴.Uber等).教育(慕课网 ...

  4. MongoDB 安装和可视化工具

    MongoDB 是一款非常热门的NoSQL,面向文档的数据库管理系统,官方下载地址是:MongoDB,博主选择的是 Enterprise Server (MongoDB 3.2.9)版本,安装在Win ...

  5. margin-top失效的解决方法

    异常处理汇总-前端系列 http://www.cnblogs.com/dunitian/p/4523015.html 我的是属于这种情况 按照网上的说法,我就是这个现象了 两个层box1和box2,b ...

  6. C#设计模式系列:建造者模式(Builder)

    1.建造者模式简介 1.1>.定义 建造者模式(Builder)将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 1.2>.使用频率 中低 1.3>.原型模式应用 ...

  7. 深入学习jQuery的三种常见动画效果

    × 目录 [1]显隐效果 [2]高度变化 [3]淡入淡出 前面的话 动画效果是jQuery吸引人的地方.通过jQuery的动画方法,能够轻松地为网页添加视觉效果,给用户一种全新的体验.jQuery动画 ...

  8. 深入学习jQuery元素过滤

    × 目录 [1]索引过滤 [2]内容过滤 前面的话 过滤是jQuery扩展的一个重要的内容.jQuery选择器中的一个重要部分就是过滤选择器.除了过滤选择器,还有专门的元素过滤的方法.本文将详细介绍j ...

  9. Util应用程序框架公共操作类(七):Lambda表达式公共操作类

    前一篇扩展了两个常用验证方法,本文将封装两个Lambda表达式操作,用来为下一篇的查询扩展服务. Lambda表达式是一种简洁的匿名函数语法,可以用它将方法作为委托参数传递.在Linq中,大量使用La ...

  10. 設置Linux保留物理內存並使用 (1)

    在Linux系統中可以通過memblock來設置系統保留物理內存,防止這些內存被內存管理系統分配出去. 作者: 彭東林 郵箱: pengdonglin137@163.com 平臺 硬件平臺: TQ24 ...