三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> ASP.NET -> C# Lambda 表达式生成 SQL 查询语句 -> 正文阅读
 

[ASP.NET]C# Lambda 表达式生成 SQL 查询语句

C# Lambda 表达式生成 SQL 查询语句 由于一些历史原因,导致公司现有项目的数据库中存在大量中文表名,中文字段名,而且操作数据库的方式还是 SQL 语句拼接 + ADO.NET,当然操作数据库的方式一点问题都没,但是最让我不能接受的就是 SQL 语句的拼接,因为数据库中大量中文表名,中文字段名的原因,导致一打开相关代码,黑压压一片汉字,着实辣眼睛,为了解决这个问题,编写了 TQueryHelper 帮助类。
TQueryHelper 的主要作用是避免在拼接 SQL 语句中出现中文,所以我的解决思路是:中文表名,中文字段名,可以利用特性(Attribute)来与实体类的属性一一映射,查询语句通过 Lambda 表达式分块生成,然后利用 StringBuilder 进行拼接,因为是在现有项目上改进,所以 LinqToSql 和 EF 都不适合,因为 LinqToSql 和 EF 都需要连接数据库创建相应的实体类,这不符合需求,加上网上没有找到期望的类库,所以打算自己造,需要说明的是,Lambda 表达式生成 SQL 参考的这篇文章《由浅入深表达式树(二)遍历表达式树 作者:腾飞(Jesse)》,在此特别感谢作者。
上面说明的是编写 TQueryHelper 动机和过程,发本文的目的是期望自己写的帮助类能够帮助其他人,避免别人重复造轮子,另外由于本文水平有限,也期望大家能给出好的建议,让本人加以改进,还有如果有现成类库,本人就可以直接使用成熟的类库,这样也避免本人继续走弯路。
下面介绍一下 TQueryHelper 生成 SQL 语句的方式,增删改查虽然都有包括,但下面只介绍查询方面的,首先我们定义两个实体类:

[DataBaseT("文章表")]
public class TopicModel
{
    public int IdentityID { get; set; }

    [DataBaseT("标题")]
    public string Title { get; set; }

    [DataBaseT("类别")]
    public string TypeCode { get; set; }
}
[DataBaseT("文章类别表")]
public class TopicTypeModel
{
    public int IdentityID { get; set; }

    [DataBaseT("编号")]
    public string TypeCode { get; set; }

    [DataBaseT("名称")]
    public string TypeName { get; set; }
}

单表简单查询代码如下:

string querySql = new TQueryHelper<TopicModel>().Query()
                  .ToSql();
//生成的 SQL 语句如下:
select [文章表].* from [文章表] with(nolock)

查询前 10 条数据,并且只查询 IdentityID 和 标题字段代码如下:

string querySql = new TQueryHelper<TopicModel>().Query(10)
                  .Select(p => new { ID = p.IdentityID, p.Title })
                  .ToSql();

//生成的 SQL 语句如下:
select top 10 [文章表].[IdentityID] as ID,[文章表].[标题] from [文章表] with(nolock)

复杂一点的单表查询,包括 Where 语句,Order By 语句,Group By 语句的代码如下:

string querySql = new TQueryHelper<TopicModel>().Query()
                  .Select(p => new { ID = p.IdentityID, p.Title })
                  .Count(p => p.IdentityID, "Count")
                  .Where(p => p.IdentityID == 1)
                  .OrderDesc(p => p.IdentityID)
                  .Group(p => new { p.IdentityID, p.Title })
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].[IdentityID] as ID,[文章表].[标题],COUNT([文章表].[IdentityID]) as [Count] from [文章表] with(nolock) where [文章表].[IdentityID] = 1 group by [文章表].[IdentityID],[文章表].[标题] order by [文章表].[IdentityID] desc

下面来看看多表查询,简单双表内联连接查询代码如下:

string querySql = new TQueryHelper<TopicModel>().Query()
                  .InnerJoin<TopicTypeModel>((p, y) => p.IdentityID == y.IdentityID)
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].* ,[文章类别表].* from [文章表] with(nolock) inner join [文章类别表] with(nolock) on [文章表].[IdentityID]=[文章类别表].[IdentityID]

复杂一点的双表内联查询代码如下:

string querySql = new TQueryHelper<TopicModel>()
                  .Query()
                  .Select(p => new { ID = p.IdentityID, p.Title })
                  .Select<TopicTypeModel>(p => new { TypeID = p.IdentityID, p.TypeCode, p.TypeName })
                  .InnerJoin<TopicTypeModel>((p, y) => p.TypeCode == y.TypeCode)
                  .Where(p => p.TypeCode == "life" && p.IdentityID <= 20)
                  .Order(p => p.IdentityID)
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].[IdentityID] as ID,[文章表].[标题],[文章类别表].[IdentityID] as TypeID,[文章类别表].[编号],[文章类别表].[名称] from [文章表] with(nolock) inner join [文章类别表] with(nolock) on [文章表].[类别]=[文章类别表].[编号] where [文章表].[类别] = 'life' and [文章表].[IdentityID] <= 20 order by [文章表].[IdentityID] asc

TQueryHelper 支持任意张表内联连接/左连接/右连接查询,TQueryHelper 也支持联合查询和子查询,简单联合查询的代码如下:

string querySql = new TQueryHelper<TopicModel>()
                  .Query()
                  .Union<TopicModel>(
                      new TQueryHelper<TopicModel>().Query()
                  )
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].* from [文章表] with(nolock) union (select [文章表].* from [文章表] with(nolock))

复杂的联合查询代码也都依然支持,通过代码也能看到,联合查询之间互相无影响,所以逻辑可以相对复杂,子查询的处理方式跟联合查询类似,From In 子查询代码如下:

string querySql = new TQueryHelper<TopicModel>()
                  .Query()
                  .Select()
                  .FromIn<TopicModel>(
                      new TQueryHelper<TopicModel>()
                      .Query()
                  )
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].* from (select [文章表].* from [文章表] with(nolock)) as [文章表]

目前只提供了 Where In 的支持,代码如下:

string querySql = new TQueryHelper<TopicModel>()
                  .Query()
                  .Select()
                  .Where(p => p.IdentityID == 1)
                  .WhereIn<TopicTypeModel>(
                      p => p.TypeCode,
                      new TQueryHelper<TopicTypeModel>()
                      .Distinct()
                      .Select(p => new { TypeCode = p.TypeCode })
                  )
                  .ToSql();

//生成的 SQL 语句如下:
select [文章表].* from [文章表] with(nolock) where [文章表].[IdentityID] = 1 and [文章表].[类别] in (select distinct [文章类别表].[编号] from [文章类别表] with(nolock) )

至此,TQueryHelper 的主要功能都介绍完毕,TQueryHelper 支持 SQL 拼接的大部分逻辑实现,当然也支持生成参数(@)的 SQL 语句,这儿不一一列出,需要说明的是,虽然支持 CacheKey(就是根据 CacheKey 把查询语句缓存出来),但是还是无法避免表达式的参数传递,因为测试发现,比如下面的代码:

private void X<T>(Expression<Func<T, object>> lambda) {}
for (int index = 0; index < 10000; index ++ )
{
    X<TopicModel>(p => new { p.IdentityID, p.Title });
}

上面的代码,X 函数里面什么也没做,但是测试之后发现竟然需要消耗大概 130 毫秒左右,这儿实在是没想出办法来优化,所以调用生成一次 SQL 之后应该根据 KEY 值及时缓存,这样下次调用可以直接从缓存中拿出已拼接好的 SQL 语句,而不再需要通过 TQueryHelper 生成 SQL 语句,最后,还是希望看过本文的朋友提出宝贵的改进意见,或者给出成熟的类库链接,本人感激不进。源码下载地址:https://pan.baidu.com/s/1jHG3mSm 密码:ytm5
  ASP.NET 最新文章
IIS服务器的请求流程
通过Web Service实现IP地址查询功能
VS 远程调试阿里云上的web站点,Remote Deb
sqlserver的四种分页方式
WebService服务(转)
C#去除字符串中的反斜杠
asp.net微信开发第三篇
Linq详细介绍
2016 .net 招聘
ASP.NET程序从IIS6移植到IIS7时出现500.22错
上一篇文章           查看所有文章
加:2017-10-26 23:25:01  更:2017-10-26 23:25:04 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-16 19:27:26
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库