为什么开发(背景)

  1. 最开始使用的是 sqlDbHelper,有微软的,有自己写的。
  2. 后来开始使用比较成熟的框架开发,使用过一段时间的Hibernate,后期主要使用 Entity FrameWork。
  3. 发现表越多 业务越复杂后,越不好控制项目,所以慢慢的自己根据业务写了一个小工具,也就是本文说的 LambdaToSql。
  4. 最开始的功能 主要是准备替代DbHelper的,慢慢的把映射关系加上了,再后来重构了几次,就慢慢的代替了EF的功能。
  5. 现在有几个成熟的项目在使用,软件也会一直维护下去,现在基本都是核心功能,暂时没往大而全去做。

ORM介绍

  1. 链式查询、链式更新、链式删除、链式插入、复杂模型的查询、ADO.NET。
  2. 支持数据库:现在只支持 MS Sql Server,其他数据库暂时未做支持处理,里面预留了对其它数据库支持的接口,但未实现代码逻辑。
  3. 数据库预留接口:Oracle、Mysql、Access。
  4. 功能: 基本CURD(添加,修改,读取,删除)功能,批量修改,DbFirst,表缓存。
  5. 全部使用Lambda语法,开发简洁,代码干净,后期好维护。
  6. 有点2:性能高,基本接近于原生ADO,语法简单,功能强大,持续更新维护。
  7. 其实LambdaToSql不能算是一个ORM,主要功能其实还应该算是Dapper替代产品,主要是把映射对象通过Lambda形式转换成sql语句,通过Ado做 CURD操作。
  8. 缺点1:不支持多表查询,Join性能还是比较低,但后期还是会支持join查询。
  9. 缺点2:暂时不支持外部自定义函数和继承覆盖重写,后期慢慢也会开放出来。
  10. 如果有想自定义的,可以直接使用源码改动哦。

性能测试

  1. 测试环境:   硬盘:三星 SSD 850 EVO;     CPU:i7-7700K
  2. 添加100w条数据 耗时大概250s内
  3. 查询100w条数据并生成实体.Tolist(),大概3s
  4. 100w数据,每页50条,取中间数据,大概100ms内
  5. 插入/更新/查询 单条数据 大概20ms内
  6. 删除 单条大概 20ms内

开源地址

  1. 码云gitee: https://gitee.com/wangshuyu/LambdaToSql
  2. Demo示例:https://gitee.com/wangshuyu/LambdaToSql_Demo

如何安装

  1. 源码方式:可以直接在gitee下载源代码,在项目中直接使用
  2. 通过Nuget下载引用: 打开Nuget  搜索:LambdaToSql 就可以了
  3. Nuget命令方式:  Install-Package LambdaToSql

Config配置,链接数据库

  <connectionStrings>
<add name="ConnectionString" connectionString="Server=.;Database=LambdaToSql;User ID=sa;Password=abc@123;" providerName="System.Data.SqlClient" />
</connectionStrings>

初始化LambdaToSql 对象

//默认方式
LambdaToSql.SqlClient DB = new LambdaToSql.SqlClient();
//自定义链接字符串名称
var DB = new LambdaToSql.SqlClient(new LambdaToSql.EntityModel.DbContext()
{
ConnectionStringName = "ConnectionString1",
SqlType = LambdaToSql.EntityModel.SqlType.MsSqlServer
});

初次使用,如何生成实体类:DbFirst

//生成实体保存路径
var saveFolder = "d:\\class\\"; //生成全部实体
DB.DbFirst.Create(saveFolder); //生成指定表实体对象
DB.DbFirst.CreateByTable(saveFolder, new List<string>() { "Table_ID", "Table_Guid" });

查询

/// <summary>
/// 查询
/// </summary>
public void Query()
{
//查询全部
var list = DB.QueryTable<EntityModel.Table_ID>().ToList(); //Find主键查找,支持Guid 和int 自增主键
var entity = DB.QueryTable<EntityModel.Table_ID>().Find(); //In查询
var arr = new int?[] { , , , }.ToList();
var list1 = DB.QueryTable<EntityModel.Table_ID>(ex => arr.Contains(ex.ID)).ToList(); //Not In 查询
var list2 = DB.QueryTable<EntityModel.Table_ID>(ex => ex.ID.ExNotIn(arr)).ToList();//有问题
var list2_1 = DB.QueryTable<EntityModel.Table_ID>(ex => arr.NotContains(ex.ID)).ToList();//有问题 // Like 查询
var list3 = DB.QueryTable<EntityModel.Table_ID>().Where(ex => ex.LoginName.Contains("")).ToList();//(LoginName like '%15%')
var list4 = DB.QueryTable<EntityModel.Table_ID>().Where(ex => ex.LoginName.NotContains("")).ToList();//(LoginName not like '%15%') //有问题
var list5 = DB.QueryTable<EntityModel.Table_ID>().Where(ex => ex.LoginName.StartsWith("")).ToList();//(LoginName like '15%')
var list6 = DB.QueryTable<EntityModel.Table_ID>().Where(ex => ex.LoginName.EndsWith("")).ToList();//(LoginName like '%15') //排序
var list7 = DB.QueryTable<EntityModel.Table_ID>().OrderBy(ex => ex.CreateTime).OrderByDescending(ex => ex.LoginName).ToList(); //分组
var list8 = DB.QueryTable<EntityModel.Table_ID>().GroupBy(ex => new { ex.LoginName, ex.UserName }).ToList(); //只取特定字段
var list9 = DB.QueryTable<EntityModel.Table_ID>().Select(ex => new { ex.LoginName, ex.UserName }).ToList(); //top N
var list10 = DB.QueryTable<EntityModel.Table_ID>().Take().ToList();
//第几页
var list11 = DB.QueryTable<EntityModel.Table_ID>().Skip().Take().ToList(); //取第一条数据
var list12 = DB.QueryTable<EntityModel.Table_ID>().First();
var list13 = DB.QueryTable<EntityModel.Table_ID>().FirstOrDefault(); //分页 2005,2008使用row_number分页,2012以上使用offset分页形式
int total = ;
var list14 = DB.QueryTable<EntityModel.Table_ID>().Skip().Take().ToPageList(ref total); //分组 select 比原始去重性能要高一些
DB.QueryTable<EntityModel.Table_ID>().GroupBy(ex => new { ex.UserName, ex.LoginName })
.Select(ex => new { ex.UserName, ex.LoginName })
.ToList(); //判断满足条件的数据是否存在
var flag = DB.QueryTable<EntityModel.Table_ID>().Any();
//判断满足条件的数据是否存在
var flag1 = DB.QueryTable<EntityModel.Table_ID>(ex => ex.ID == ).Any();
}

函数处理

/// <summary>
/// 函数处理
/// </summary>
private void Fun()
{
//求和
var num1 = DB.QueryTable<EntityModel.Table_ID>().Sum(ex => ex.IsDelete); //最小值
var num2 = DB.QueryTable<EntityModel.Table_ID>().Min(ex => ex.IsDelete); //最大值
var num3 = DB.QueryTable<EntityModel.Table_ID>().Max(ex => ex.IsDelete); //平均值
var num4 = DB.QueryTable<EntityModel.Table_ID>().Avg(ex => ex.IsDelete); //总数
var num5 = DB.QueryTable<EntityModel.Table_ID>().Count();
}

添加

/// <summary>
/// 添加数据
/// </summary>
public void Inser()
{
//添加单个实体对象
var entity = new EntityModel.Table_ID()
{
LoginName = "登录用户:",
UserName = "用户名:",
PassWord = "密码-",
Gender = "男",
IsDelete = ,
Mobile = "",
Remark = "备注",
Address = "地址:",
CreateTime = DateTime.Now
};
var ret = DB.InsertTble(entity).ExecuteNonQuery();//返回主键值 //只添加某几列
var i = DB.InsertTble(entity).InsertColumns(ex => new { ex.LoginName, ex.UserName, ex.Remark }).ExecuteNonQuery(); //忽略某些列
var i1 = DB.InsertTble(entity).IgnoreColumns(ex => new { ex.Mobile, ex.PassWord }).ExecuteNonQuery();
}

修改

  1. NULL列不做更新处理
  2. 暂时只支持uniqueidentifier和int自增类型单主键
/// <summary>
/// 更新数据
/// </summary>
public void Update()
{
//更新单个实体对象
var entity = DB.QueryTable<EntityModel.Table_ID>(ex => ex.ID == ).FirstOrDefault();
entity.PassWord = "";
entity.LoginName = "LambdaToSql";
entity.UserName = "LambdaToSql1";
var i = DB.UpdateTble(entity).ExecuteNonQuery(); //更新特定字段,不指定不更新
var i1 = DB.UpdateTble(entity).UpdateColumns(ex => new { ex.PassWord }).ExecuteNonQuery(); //忽略特定字段,其他字段都更新
var i2 = DB.UpdateTble(entity).IgnoreColumns(ex => new { ex.UserName, ex.PassWord }).ExecuteNonQuery(); //条件更新 不需要取出实体对象 直接数据库更新
var i3 = DB.UpdateTble(new EntityModel.Table_ID() { PassWord = "", LoginName = "" }).Where(ex => ex.ID == ).ExecuteNonQuery(true);
}

删除

/// <summary>
/// 删除
/// </summary>
public void Delete()
{
//删除单个实体,通过主键删除
var entity = DB.QueryTable<EntityModel.Table_ID>(ex => ex.ID == ).FirstOrDefault();
var i = DB.DeleteTble<EntityModel.Table_ID>(entity).ExecuteNonQuery(); //条件删除 支持查询里面的所有条件写法
var i1 = DB.DeleteTble<EntityModel.Table_ID>(ex => ex.ID == ).ExecuteNonQuery();
}

事务

事务使用注意:

  1. 事务只能在同一个SqlClient对象有效;事务只能在同一个SqlClient对象有效;事务只能在同一个SqlClient对象有效;重要的事说三遍
  2. 跨SqlClient对象请用分布式事务(暂时内置不支持,后续版本会支持分布式事务)
/// <summary>
/// 事务
/// </summary>
public void Tran()
{
var sqlClient = new LambdaToSql.SqlClient();
try
{
sqlClient.BeginTran();//开启事务 //添加单个实体对象
var entity = new EntityModel.Table_ID()
{
LoginName = "登录用户:",
UserName = "用户名:",
PassWord = "密码-",
IsDelete = ,
CreateTime = DateTime.Now
};
var entity1 = new EntityModel.Table_ID()
{
LoginName = "登录用户:",
UserName = "在破败中崛起,在寂灭中复苏。沧海成尘,雷电枯竭,那一缕幽雾又一次临近大地,世间的枷锁被打开了,一个全新的世界就此揭开神秘的一角:",
PassWord = "密码-",
IsDelete = ,
CreateTime = DateTime.Now
};
var entity2 = new EntityModel.Table_ID()
{
LoginName = "登录用户:",
UserName = "用户名:",
PassWord = "密码-",
IsDelete = ,
CreateTime = DateTime.Now
}; sqlClient.InsertTble(entity).ExecuteNonQuery();
sqlClient.InsertTble(entity1).ExecuteNonQuery();//错误 UserName太长=>回滚
sqlClient.InsertTble(entity2).ExecuteNonQuery(); sqlClient.CommitTran();//提交事务
}
catch (Exception ex)
{
sqlClient.RollbackTran();//回滚事务
}
}

ADO

/// <summary>
/// Ado
/// </summary>
public void Ado()
{
var sql = "select top(10) * from table_id";
var sdr = DB.Ado.ExecuteReader(sql);
var list = new List<string>();
while (sdr.Read())
{
list.Add(sdr[].ToString());
}
sdr.Close(); var Dt = DB.Ado.ExecuteTable(sql); var ls1 = DB.Ado.ExecuteScalar(sql);
var ls = DB.Ado.ExecuteScalars(sql); var i = DB.Ado.ExecuteNonQuery("update top (10) table_id set imgurl = 'img1'");
}

后续计划

  1. 继续维护代码和升级新功能
  2. 把类库UML图发布出来
  3. 把类接口和实现文档 整理好 发布出来
  4. 会在开源一个关于WebApi的整体框架结构
  5. 最近另一个开源项目: https://gitee.com/wangshuyu/CommonLib  这是个通用类库项目,把平时常用的整理了下,自己也一直在使用此类库

结尾

  1. 希望大家多多提bug
  2. 希望大家多多提意见
  3. 最后,感谢SqlSugar项目作者开源

LambdaToSql(轻量级ORM) 入门篇 开源项目的更多相关文章

  1. 08_android入门_android-async-http开源项目介绍及用法

    android-async-http开源项目可以是我们轻松的获取网络数据或者向server发送数据.使用起来很easy,关于android-async-http开源项目的介绍内容来自于官方:http: ...

  2. SqlSugar ORM 入门篇2 【查询】 让我们实现零SQL

    SqlSugar在查询的功能是非常强大的,多表查询.分页查询 . 一对一查询.二级缓存.一对多查.WhenCase等复杂函数.Mapper功能.和拉姆达自定义扩展等,用好了是可以做到真正零SQL的一款 ...

  3. 手写ORM入门篇(一)

    对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 . ...

  4. Android 开源项目及其学习

    Android 系统研究:http://blog.csdn.net/luoshengyang/article/details/8923485 Android 腾讯技术人员博客 http://hukai ...

  5. Farseer.net轻量级ORM开源框架 V1.x 入门篇:存储过程数据操作

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:存储过程实体类映射 下一篇:Farseer.net轻量级ORM ...

  6. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库上下文

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件 下一篇:Farseer.net轻量级ORM开源 ...

  7. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明 下一篇:Farseer.net轻量级ORM开源框架 ...

  8. Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:没有了 下一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置 前言 V1.x版本终于到来了.本次 ...

  9. Farseer.net轻量级ORM开源框架 V1.x 入门篇:视图的数据操作

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:视图实体类映射 下一篇:Farseer.net轻量级ORM开源 ...

随机推荐

  1. dfs.replication、dfs.replication.min/max及dfs.safemode.threshold.pct

    一.参数含义 dfs.replication:设置数据块应该被复制的份数: dfs.replication.min:所规定的数据块副本的最小份数: dfs.replication.max:所规定的数据 ...

  2. 【Nginx】关于域名转发proxy_pass

    在配置nginx的时候,有一个需求,访问m.XXX.com的时候,需要实际访问www.YYY.com/m,并且域名不能发生变化. 达成这个需求有两种做法: 第一种就是301跳转,使用rewrite来跳 ...

  3. Oracle 行列转换总结

    行列转换包括以下六种情况:*列转行*行转列*多列转换成字符串*多行转换成字符串*字符串转换成多列*字符串转换成多行 下面分别进行举例介绍. 首先声明一点,有些例子需要如下10g及以后才有的知识:a.掌 ...

  4. 九度oj 1004 Median 2011年浙江大学计算机及软件工程研究生机试真题

    题目1004:Median 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:14162 解决:3887 题目描述: Given an increasing sequence S of N i ...

  5. jquery清空下拉框,保留第一个

    js中可以document.getElementById("id").options.length = 1;设置 jquery中的设置方法:$("#id option[i ...

  6. Redis 小结

    一.redis简介 redis是一款基于C语言编写的,开源的非关系型数据库,由于其卓越的数据处理机制(按照规则,将常用的部分数据放置缓存,其余数据序列化到硬盘),大家也通常将其当做缓存服务器来使用. ...

  7. 实现 如 goole closure 类似功能模块加载函数

    看过goole  closure 的同学都知道  其中定义一个类名函数时候只要  inlude("")   想加载某个模块只要require("")就可以利用: ...

  8. PostgreSQL PARTITION 分区表

    PostgreSQL 分区表,操作性相当便捷. 但只能在创建时决定是否为分区表,并决定分区条件字段,普通表创建后,不能在修改为分区表. Note:通过其他方法也可转化为分区表. 和其他数据库一样,分区 ...

  9. C# 连接Oracle,进行查询,插入操作

    注:OracleConnection和OracleCommand已被标注为[弃用的],可以使用System.Data.OleDb.OleDbConnection代替OracleCOnnection,使 ...

  10. PHP学习2——基本语法

    主要内容: 二进制 数据类型 变量 常量 赋值 语句结构 函数 网站的核心功能是展现信息,文字,图片,视频,音频,对于计算机来说都是数据,这些数据按照二进制进行存储. 二进制 就是1100,0100, ...