Dapper.Common基于Dapper的开源LINQ超轻量扩展
Dapper.Common
Dapper.Common是基于Dapper的LINQ实现,支持.net core,遵循Linq语法规则、链式调用、配置简单、上手快,支持Mysql,Sqlserver(目前只实现了这两个数据库,实现其他数据库也很轻松),支持单表,多表,自定义函数等功能。源码及其简单,直白,解析Lambda只有300行左右代码。严格区分C#函数和数据库函数,你可以在表达式中调用C#函数(不推荐,推荐将计算结果保存到变量,在写入lambda表达式),性能损失在表达式编译:常量>变量>函数。损失多少可以通过ExpressionUtil.BuildExpression()来测试,几万次耗时百毫秒及别。
开源地址:https://github.com/1448376744/Dapper.Common
Nuget:Install-Package Dapper.Common -Version 1.5.0
0.Test


1.Mapper
public class User
{
/// <summary>
/// 如果表名与字段名一致,可以不用Column进行注解,主键采用类型的第一个属性【不推荐】
/// name:用于映射字段名和数据库字段不一致【完全可以用T4一键生成我GitHub有现成的】
/// key:
/// 目前实现了Primary的定义,设置为Primary的字段update实体时,默认采用该字段为更新条件
/// isIdentity:
/// 设置未true时在Insert时不会向该字段设置任何值
/// isColumn:
/// 标识该字段是否在数据库存在,用于扩展User而不在sql中生成该字段
/// </summary>
[Column(name: "id", key: ColumnKey.Primary, isIdentity: true, isColumn: true)]
public int? Id { get; set; }
[Column(name:"nick_name")]
public string NickName { get; set; }
[Column(name: "create_time")]
public DateTime? CreateTime { get; set; }
}
2.Config
//在App启动时执行一次即可
SessionFactory.AddDataSource(new DataSource()
{
Name = "mysql",
Source = () => new SqlConnection("connectionString"),
SourceType = DataSourceType.SQLSERVER,
UseProxy = true//使用Session的静态代理实现,记录日志,执行耗时,线上环境建议关闭代理
});
//获取数据库上下文
using (var session = SessionFactory.GetSession("msql"))
{
//linq to sql
}
3.Insert
var entity = new User()
{
CreateTime=DateTime.Now,
NickName="dapper",
};
//绝大部分接口可以设置condition已决定是否执行,支持批量更新
session.From<User>().Insert(entity,condition:>);
//查看日志,如果出现异常,应该在catch里,查看session.Loggers
var loggers = session.Loggers;
2.Update
var entity = new User()
{
Id=2,
NickName="李四"
};
//更新所有字段(where id=2),支持批量,显然除NickName之外将被更新成null
session.From<User>().Update(entity); //更新部分字段
session.From<User>()
.Set(a => a.NickName, "李四", condition: true)//condition为true时更新该字段
.Set(a => a.Balance, a => a.Balance + )//余额在原来基础增加100
.Where(a => a.Id.In(,,))//将id为1,2,3的记录进行更新
.Update();
3.Delete
//删除id>5||nick_name like '%da%'
session.From<User>()
.Where(a=>a.Id>||a.NickName.Like("da"))
.Delete();
4.Single
//查询全部字段
var user1 = session.From<User>()
.Where(a=>a.Id==)
.Single(); //查询部分字段
var user2 = session.From<User>()
.Where(a => a.Id == )
.Single(s=>new
{
s.Id,
s.NickName
});
5.Select
//查询:where id in(1,2,3)
var list = session.From<User>()
.Where(a => a.Id.In("1,2,3".Split(',')))
.Select();
6.Where
//构建动态查询,condition: true执行,通过condition选择分支,多个where之间用 and 连接
var list = session.From<User>()
.Where(a => a.Id.In(, , ), condition: true)
.Where(a => a.NickName.Like("da"), condition: false)
.Where(a => a.Id > || (a.NickName.Like("da") && a.Balance > ))
.Where("select * from user_bill where user_bill.user_id=user.id")//同样可以当作字符串拼接工具
.Select();
7.Function
/// <summary>
/// 自定义函数
/// </summary>
public static class MySqlFun
{
//这里使用泛型并不是必须的,只用函数名在数据库存在即可,泛型为了指定返回数据类型
[Function]//Dapper.Common严格区分C#函数和数据库函数,一定要用该特性标识数据库函数
public static T COUNT<T>(T column)
{
return default(T);
}
[Function]
public static T MAX<T>(T column)
{
return default(T);
}
[Function]
public static T DISTINCT<T>(T column)
{
return default(T);
}
[Function]
public static T DATE<T>(T column)
{
return default(T);
}
}
8.GroupBy
var list = session.From<Order>()
.GroupBy(a => a.UserId)//多个条件可以new一个匿名对象,也可以并联多个group
.Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > )//count(distinct(user_id))>10
.Select(s => new
{
s.UserId,
OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int,
MaxFee = MySqlFun.MAX(s.TotalFee)
});
9.Join
var list = session.From<Order, User>()
.Join((a, b) => a.UserId == b.Id, JoinType.Inner)
.GroupBy((a, b) => a.UserId)
.Having((a, b) => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > )//count(distinct(user_id))>10
.Select((a, b) => new
{
a.UserId,
b.NickName,
OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int,
MaxFee = MySqlFun.MAX(a.TotalFee)
});
10.SubQuery
var list = session.From<Order>()
.GroupBy(a => a.UserId)
.Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > )
.Select(a => new
{
a.UserId,
UserName=Convert.ToString("select nick_name from user where user.id=order.user_id"),//如果这个子查询返回的是int:Convert.ToInt32(sql)
OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int【这就是为什么定义成泛型函数】,
MaxFee = MySqlFun.MAX(a.TotalFee)
});
11.Page
//分页应该写在Where,Having,Group之后(如果有)
var list = session.From<User>()
.Where(a=>a.NickName != null)
.Page(,,out long total)
.Select();
12.Take
var list = session.From<User>()
.Take()
.Select();
13.Skip
//从数据库索引为1的位置(跳过1之前的记录),获取10
var list = session.From<User>()
.Skip(,)
.Select();
14.Sum
var list= session.From<User>()
.Sum(s=>s.Balance*s.Id);
15.Exists
//内部采用exist子查询判断满足where条件的记录是否存在
var flag = seesion.From<User>()
.Where(a=>a.Id > )
.Exists();
16.OrderBy
var list1 = session.From<User>()
.Order(a=>a.Id)
.Select(); var list2 = session.From<User>()
.GroupBy(a => MysqlFun.DATE(a.CreateTime))
.OrderByDescending(a => MysqlFun.DATE(a.CreateTime))
.Select(s=>new
{
Date=MysqlFun.DATE(s.CreateTime),
Count = MysqlFun.Count(1L)
});
17.Filter
var user =new User ()
{
Id = 12
Balance = ,
NickName = "张三",
CreateTime = Datetime.Now
};
//Filter会在Insert,Update,Select,过滤掉不想要的字段
//这将不会更新余额及创建时间
var row = session.From<User>()
.Filter(f=>new
{
f.CreateTime,
f.Balance,
})
.Update(user);
18.Transaction
//获取数据库上下文
ISession session = null;
try
{
session=SessionFactory.GetSession();
//开启事务
session.Open(true);
//sql
//提交事务
session.Commit();
}
catch (Exception)
{
session?.Rollback();
throw;
}
finally
{
session?.Close();
}
19.Custom Page
//该策略可适用于百万级别,单表条件查询
//思想:先只查满足条件的id,并分页,然后where in (idArray)查详情
//还有一种超高性能的分页思想:每一页更具上一页最大id开始向下分页查询,同样可以集成到这一个方法里(加个分页类型参数)
public static Dapper.Extension.IQueryable<T> SPage<T>(this Dapper.Extension.IQueryable<T> queryable, int index, int count, out long total) where T : class, new()
{
total = ;
if (index <= )
{
//采用limit
queryable.Page(index, count, out total);
}
//对mysql进行扩展
else if (queryable is MysqlQuery<T> mysqlQuery)
{
total = queryable.Count();
var table = EntityUtil.GetTable<T>();
var idName = table.Columns.Find(f => f.ColumnKey == ColumnKey.Primary).ColumnName;
//先只查询主键字段并分页
var where = mysqlQuery._whereBuffer.Length > ? "where " + mysqlQuery._whereBuffer : "";
var orderby = mysqlQuery._orderBuffer.Length > ? "order by" + mysqlQuery._orderBuffer : "";
var sql = string.Format("select {0} from {1} {2} {3} limit {4},{5}", idName, table.TableName, where, orderby, (index - ) * count, count);
var idArray = mysqlQuery._session.Query<long>(sql, mysqlQuery._param);
//重置
mysqlQuery._whereBuffer.Clear();
//新建条件
if (idArray.Count() > )
{
queryable.Where(string.Format("{0} in @idArray", idName), p => p.Add("@idArray", idArray));
}
}
return queryable;
} var row = Session.From<Member>()
.SPage(,,out long total)
.Select();
Dapper.Common基于Dapper的开源LINQ超轻量扩展的更多相关文章
- Dapper扩展Dapper.Common框架 Linq To Sql 底层源码.net ORM框架
源代码:https://github.com/1448376744/Dapper.CommonNUGET: Dapper.CommonQQ群:642555086 一.基本结构,此处可用委托,或动态代理 ...
- 基于Dapper的开源LINQ扩展,且支持分库分表自动生成实体二
LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼. 文档地址: https://lining ...
- 基于Dapper的开源Lambda扩展LnskyDB 2.0已支持多表查询
LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼. 文档地址: https://lining ...
- 基于Dapper的开源Lambda扩展,且支持分库分表自动生成实体之基础介绍
LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼. 文档地址: https://lining ...
- 基于Dapper的开源Lambda扩展LnskyDB 3.0已支持Mysql数据库
LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼.,现在已经支持MySql和Sql serv ...
- .net core 基于Dapper 的分库分表开源框架(core-data)
一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...
- 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil
基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...
- 【原创】打造基于Dapper的数据访问层
[原创]打造基于Dapper的数据访问层 前言 闲来无事,花几天功夫将之前项目里用到的一个数据访问层整理了出来.实现单个实体的增删改查,可执行存储过程,可输出返回参数,查询结果集可根据实际情况返回 ...
- SlickOne -- 基于Dapper, Mvc和WebAPI 的快速开发框架
前言:在两年前,项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实践和应用,今再次对SlickOne项目做以回顾和总结.其目的是精简,持续改进,保持重 ...
随机推荐
- sqlserver 2008 创建数据库的时候不是空库,里面总有数据的解决办法
SqlServer2008 里面有个系统数据库 Model 数据库,在创建新数据库的时候,会以它为模板创建,所以如果发现你的Model数据库比较大,说明里面有很多模板数据.此时如果需要去创建没有数据的 ...
- web应用组成结构,web.xml的作用
- Queue 输出数据
坑人的引用类型....输出看看结果是什么 Queue<ParaInfo> strStranList = new Queue<ParaInfo>(); StringBuilder ...
- Unity3D连接WCF
Unity3D连接WCF: 一.最简单的案例 1.VS2015中: (1)建立WCF应用服务程序ForUnity: (2)将自动生成的IService1.cs与Service1.svc删除: (3 ...
- MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理
问题描述: 第一次访问的时候很慢,后面再次打开页面很快,过了一段时间不访问页面然后再次打开页面又像第一次那样很慢. 采用的技术和环境: 使用技术:EF6+MVC5 服务器环境:Windows 2012 ...
- printf 小代码 大问题
技术 对于我来说 是我前进的动力 虽然有时候感觉会枯燥乏味 不过没关系 放松一下紧张的心态 做一些你能够是你进步的事情 这样 你才会觉得 每天都过得很充实 学海无涯 坚持追求你所想要实现的梦想 ...
- 查看字符串的编码chardet
The Universal Character Encoding Detector chardet.detect("str") 返回:{‘confidence’:1.0,'enco ...
- 继续学习C:数字进制表示
1. 数字后面跟D表示十进制,如:123D. 2. 数字后面跟B表示二进制,如:10010B. 3. 数字后面跟Q表示八进制,如:652Q. 4. 数字后面跟H表示十六进制,如:2B5H. 把十进制数 ...
- qduoj 218 签到题
Description a坤和大明在一块由n个方块组成的棋盘(1 × n)上做游戏.一开始a坤在棋盘上放了k个矩形并且没有告诉大明具体位置.每个矩形都占a个连续方块(1 × a),任意两个矩形不可重叠 ...
- 汇编题目:在DOS下,按F1键后改变当前屏幕的显示颜色
我们都知道int9中断是键盘的按键中断程序,按下键盘触发int9中断,不懂int9中断的请自己去百度查查说明和用法 利用中断任务安装一个新的int 9中断例程,功能:在DOS下,按F1键后改变当前屏幕 ...