Git.Framework 框架随手记--ORM条件组合

  在上一篇<Git.Framework
框架随手记--ORM新增操作
>中简单记录了如何对数据进行删除和修改,其用法都非常简单,在文章中提到了Where()方法,本文将详述Where()
等条件函数。

  一. SQL 条件分析

    对于SQL每个人应该都很熟悉,这是基础的基础,如果没有使用过SQL的本文可以直接忽略了。先简单看看一个SQL语句,我们根据SQL语句的规则理解Where()方法


SELECT [ID],[UserName],[PassWord],[UserCode],[RealName],[Email],[Mobile],[Phone],[CreateTime],[CreateIp],[CreateUser],[LoginCount],[Picture],[UpdateTime],[IsDelete],[Status],[DepartNum],[ParentCode],[RoleNum],[Remark]
FROM [JooShowGit].[dbo].[Admin]
WHERE [UserCode]=@UserCode AND [IsDelete]=@IsDelete OR [Phone]=@Phone

    SQL语句中后面起始条件关键字必定是WHERE,这个毋庸置疑。如果后面要跟其他的条件我们就可以使用AND 或者 OR
关键字将其连接起来。SQL条件语句基本可以归纳为如下

SELECT * FROM TABLE WHERE [表达式] (AND|OR) [表达式] ....

    再看看一个稍微复杂点的SQL语句,代码如下


SELECT [ID],[UserName],[PassWord],[UserCode],[RealName],[Email],[Mobile],[Phone],[CreateTime],[CreateIp],[CreateUser],[LoginCount],[Picture],[UpdateTime],[IsDelete],[Status],[DepartNum],[ParentCode],[RoleNum],[Remark]
FROM [JooShowGit].[dbo].[Admin]
WHERE ([UserCode]=@UserCode1 OR [UserCode]=@UserCode2) AND [IsDelete]=@IsDelete

    语句是什么意思,看官一看就能够明白,我们看重点部分 ,这个SQL语句使用了 () 运算符, 两个条件 () 和
 [IsDelete][email protected] 使用AND连接的,在()运算符中又是多个单个表达式的组合。

    在看看单个表达式的效果

WHERE [UserCode]=@UserCode AND [IsDelete]=@IsDelete OR [Phone]=@Phone

    表达式可以抽象理解为  字段 [运算符] 值 这种情况。在SQL中有很多运算符,这里我们看看详细:

+(加)、―(减)、(乘)、(除)、%(取余)>(大于)<(小于)、= (等于)、>=(大于等于)、<=(小于等于)、<> (不等于)、!=(不等于)、!>(不大于)!<( 不小于)

    当然其他的运算符(AND OR 也称作运算符),我们先做一些简单的。

    以上问题说的比较含糊,表述可能不清晰,但是大家应该都能够明白其大概意思,从以上的比较可以看出其实SQL是有一定规则的。

  二. 框架中提供的条件方法

    在做ORM映射的过程中,我们对条件操作的运算符也做了相应的映射,其映射为了一个枚举值

public enum ECondition
{
/// <summary>
/// AND
/// </summary>
//And =1 ,

/// <summary>
/// OR
/// </summary>
//Or =2 ,

/// <summary>
/// LIKE
/// </summary>
Like = 3,

/// <summary>
/// IN
/// </summary>
In = 4,

/// <summary>
/// 大于 >
/// </summary>
Gth = 5,

/// <summary>
/// 小于 <
/// </summary>
Lth = 6,

/// <summary>
/// 等于 =
/// </summary>
Eth = 7,

/// <summary>
/// 大于等于 >=
/// </summary>
Geth = 8,

/// <summary>
/// 小于等于 <=
/// </summary>
Leth = 9,

/// <summary>
/// 不等于 !=
/// </summary>
NotEth = 10,

/// <summary>
/// Is 关键字
/// </summary>
Is = 11,

/// <summary>
/// Is Not 关键字
/// </summary>
IsNot = 12,

/// <summary>
/// Between AND关键字
/// </summary>
Between = 13,

/// <summary>
/// OR LIKE
/// </summary>
OrLike = 14,

/// <summary>
/// OR IN
/// </summary>
OrIn = 15,

/// <summary>
/// OR 字段>
/// </summary>
OrGth = 16,

OrLth = 17,

OrEth = 18,

OrGeth = 19,

OrLeth = 20,

OrNotEth = 21,

OrIs = 22,

OrIsNot = 23,

OrBetween = 24,

/// <summary>
/// +=
/// </summary>
AddEth=25,

/// <summary>
/// -=
/// </summary>
SubtractEth=26,

/// <summary>
/// *=
/// </summary>
MultiplyEth=27,

/// <summary>
/// /=
/// </summary>
DivideEth=28,

/// <summary>
/// %
/// </summary>
Modulo=29,

/// <summary>
/// +
/// </summary>
Add=30,

/// <summary>
/// -
/// </summary>
Subtract = 31,

/// <summary>
/// *
/// </summary>
Multiply = 32,

/// <summary>
/// /
/// </summary>
Divide=33
}

ECondition 运算符枚举

    其中有些枚举值有点奇怪,当时为了配合理解SQL语法,其中在对() 运算的时候采用了特殊的标记,我们会使用特定的方法来代替。


public void Or(string propertyName, ECondition condition);
public void Or(string propertyName, ECondition condition, params object[] values);
public void OrBegin();public void Where(string propertyName, ECondition condition);
public void Where(string propertyName, ECondition condition, params object[] values);
public void WhereBegin();
public void And(string propertyName, ECondition condition);
public void And(string propertyName, ECondition condition, params object[] values);
public void AndBegin();
public void Begin();public void End();

    这个地方有点意思,我们将WHERE,AND,OR三个连接运算符映射成了相应的方法,其中更加奇怪的是有OrBegin(),WhereBegin(),AndBegin(),Begin(),End()几个方法。上面在分析SQL的时候主要到了()
运算符,这几个方法就是为了对()特殊优待,当时设计的时候为了更好的理解() ,将()分为了两部分 ,分别对应 Begin() ,End(); 也就是前 "("
和 ")" 而其余的几个就是对其扩展 。

WHERE ([UserCode]=@UserCode1 OR [UserCode]=@UserCode2) AND [IsDelete]=@IsDelete

    其实也就可以立即为 WhereBegin(); ANND();  OR (); END();
这种调用就好比将写SQL的手法转化为命令模式。
很多对此不能够很好的理解,也对此嗤之以鼻,不要紧这只是理解的角度不一样而已,而且在对WHERE等方法向Lambda表达式转化的时候强制不能使用复合条件,避免Linq和EF中的太多层次的嵌套导致自己也晕了。

    对于上面的一些方法我们还做了一些扩展,主要扩展方法如下:


public static T And<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity;
public static T And<T>(this T entity, string propertyName, ECondition condition) where T : BaseEntity;
public static T And<T>(this T entity, string propertyName, ECondition condition, params object[] values) where T : BaseEntity;
public static T AndBegin<T>(this T entity) where T : BaseEntity;
public static T Begin<T>(this T entity) where T : BaseEntity;
public static T Between<T>(this T entity, string propertyName, object[] items) where T : BaseEntity;
public static T End<T>(this T entity) where T : BaseEntity;
public static T Or<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity;
public static T Or<T>(this T entity, string propertyName, ECondition condition) where T : BaseEntity;
public static T Or<T>(this T entity, string propertyName, ECondition condition, params object[] values) where T : BaseEntity;
public static T OrBegin<T>(this T entity) where T : BaseEntity;
public static T Where<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity;
public static T Where<T>(this T entity, string propertyName, ECondition condition) where T : BaseEntity;
public static T Where<T>(this T entity, string propertyName, ECondition condition, params object[] values) where T : BaseEntity;
public static T WhereBegin<T>(this T entity) where T : BaseEntity;

  三. 使用实例

entity.IncludeAll();
entity.Where(a => a.IsDelete == (int)EIsDelete.NotDelete);

    这个条件语句在之前已经解析过了,就是WHERE [IsDelete]= (int)EIsDelete.NotDelete .

entity.IncludeAll();
entity.Where("IsDelete", ECondition.Eth,(int)EIsDelete.NotDelete);

    上面这两段代码其实是等价的,只是后一种是使用Lambda表达式来解析的,最终的结果都一样。


SELECT t0.[ID],t0.[UserName],t0.[PassWord],t0.[UserCode],t0.[RealName],t0.[Email],t0.[Mobile],t0.[Phone],t0.[CreateTime],t0.[CreateIp],t0.[CreateUser],t0.[LoginCount],t0.[Picture],t0.[UpdateTime],t0.[IsDelete],t0.[Status],t0.[DepartNum],t0.[ParentCode],t0.[RoleNum],t0.[Remark],t1.[RoleName] AS RoleName FROM [dbo].[Admin] AS t0  LEFT JOIN [dbo].[SysRole] AS t1 ON  t0.[RoleNum]=t1.[RoleNum]  WHERE t0.[IsDelete]=@0_t0_ISDelete

     上面的方法调用最终生成的SQL如上,我们中重点看WHERE后面的,如果对比起来应该都能够理解了

DateTime beginTime = ConvertHelper.ToType<DateTime>(begin);
DateTime endTime = ConvertHelper.ToType<DateTime>(end);
entity.And<T_EXECUTEEntity>("execute_start_time", ECondition.Between, beginTime, endTime).And<T_EXECUTEEntity>("execute_end_time", ECondition.IsNot, null); ;

    

时间: 2024-08-05 19:07:11

Git.Framework 框架随手记--ORM条件组合的相关文章

Git.Framework 框架随手记--ORM项目工程

前面已经简单介绍过了该框架(不一定是框架),本文开始重点记录其使用过程.可能记录的内容不是太详尽,框架也可能非常烂,但是里面的代码句句是实战项目所得.本文非教唆之类的文章,也非批判之类的文章,更不是炫技之类的文章,只是工作的记录和总结,希望能够给大家一些启迪,忘诸位勿喷! 一. 组建项目需要的几个部分 .NET中最为经典的三层结构,众所周知,无人不晓. 在Git.Framework框架中我们也遵循最基本的这种结构,ORM部分我们划分为如下: 数据实体层,数据访问接口层,数据访问层,[层序主入口加

Git.Framework 框架随手记--ORM查询返回实体对象

使用ORM有一个优势,可以通过某种机制将数据库中的数据转化为自己想要的对象形式数据.本章记录一下如何使用Git.Framework返回实体对象 一. Git.Framework 中提供的方法 在Git.Framework中有七个方法可以返回实体对象,先简答的看看这里的方法描述 (1) T GetSingle(int id); (2) T GetSingle(object value); (3) T GetSingle(T entity); (4) V GetSingle<V>(T entity

Git.Framework 框架随手记--ORM新增操作

本篇主要记录具体如何新增数据,废话不多说,开始进入正文. 一. 生成工程结构 上一篇已经说到了如何生成工程结构,这里在累述一次. 1. 新建项目总体结构 使用VS新建项目结构,分层结构可以随意.我们使用的结构如下: 2. 引入配置文件相关 Configs文件夹中的配置文件,其目录结构如下图: 以上几个文件为必须的,除了最下面的画红线的为自定义可以修改,具体配置项内容可以参考前面几篇文章.然后再web.config定义如下配置: <appSettings> <add key="D

Git.Framework 框架随手记--ORM查询数据集合 一

本文记录Git.Framework之ORM中最为浓墨重彩的一篇,查询集合.根据自己做的项目统计这个是使用频率最高的一个. 一. 查询集合方法简介 (1)List<T> GetList(); (2)List<T> GetList(bool isOpenTrans); (3)List<T> GetList(T entity); (4)List<V> GetList<V>(T entity) where V : class, new(); (5)Lis

Git.Framework 框架随手记--存储过程简化

在很多的ORM中对存储过程操作都是一个棘手的地方,因为存储过程是一段预编译的代码,其中可以包含很多处理过程.在Git.Framework中也同样存在这样的问题,目前没有能力解决这个问题.但是对于存储过程的一些外围操作目前还是可以支持的. 上一篇文章简单回顾地址,可能对了解本文有益: Git.Framework 框架随手记--SQL配置文件的使用 一. 结构简单说明 在前面操作基本SQL的时候我们已经知道使用对象模型映射其相关的表,一些基本的操作我们都能够实现完成.在很大的程度上完成了抽象工作,在

Git.Framework 框架随手记--SQL配置文件的使用

前面几篇文章讲到了如何使用框架进行简单结构的增删改查操作,由于个人能力有限在对于复杂的SQL操作面前也是无能为力,只能自己动手来写SQL语句.在Git.Framework中提供了一个公共的接口来直接操作SQL语句. 一. SQL配置文件的结构简介 在这个框架中提供了单独的配置文件用于来管理SQL语句,当然也可以不用配置文件.使用SQL配置文件系统在启动的时候会直接将SQL配置文件转化为Command对象缓存,而不用后期再去创建,这是一个比较不错的优势.下面先看看SQL配置文件的结构 <dataO

Git.Framework 框架随手记--IIS7运行序列化问题

客户反馈系统又登录不了,这是最近几次连续出现相同的问题,从日志反应情况来看: 日志级别:[info] 日志位置:Git.Framework.Resource.ResourceManager 日志时间:2014/12/3 9:08:30 日志内容:反序列化异常:Unable to generate a temporary class (result=1). error CS1567: Error generating Win32 resource: 另一个程序正在使用此文件,进程无法访问. 日志级

DRF (Django REST framework) 框架介绍

Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 1 前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口. 2 前后端分离 在前后端分离的应用模式中,后端仅返

net.sz.framework 框架 轻松搭建数据服务中心----读写分离数据一致性,滑动缓存

前言 前文讲述了net.sz.framework 框架的基础实现功能,本文主讲 net.sz.framework.db 和 net.sz.framework.szthread; net.sz.framework.db 是 net.sz.framework 底层框架下的orm框架,仿照翻译了hibernate实现功能,虽然不足hibernate强大:但在于其功能实现单一高效和高可控性: net.sz.framework.szthread 是 net.sz.framework 底层框架下的线程控制中