自研ORM框架 实现类似EF Core Include 拆分查询 支持自定义条件、排序、选择
Baozi, I'm Mr.Zhong I like to brush TikTok, I know that anchors like to call it that, haha!
Recently, I haven't been so busy, and it took almost a day to add some APIs to the self-developed ORM framework to perfectly implement the Include query
宝子们,我是 Mr.Zhong 喜欢刷抖音都知道 主播都喜欢这么叫,哈哈!
最近没那么忙了,抽空给自研的ORM 框架新增一些API 花了将近一天的时间 完美实现 Include 查询
一、接口定义
1 /// <summary>
2 /// 包括接口类
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 /// <typeparam name="TProperty"></typeparam>
6 public interface IInclude<T, TProperty> : IQuery<T> where TProperty : class, new()
7 {
8 /// <summary>
9 /// Ado
10 /// </summary>
11 IAdo Ado { get; }
12 }
二、接口实现
1 /// <summary>
2 /// 包括实现类
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class IncludeProvider<T, TProperty> : QueryProvider<T>, IInclude<T, TProperty> where TProperty : class, new()
6 {
7 /// <summary>
8 /// Ado
9 /// </summary>
10 public IAdo Ado { get; }
11
12 /// <summary>
13 /// 构造方法
14 /// </summary>
15 /// <param name="ado"></param>
16 /// <param name="queryBuilder">查询构建</param>
17 public IncludeProvider(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
18 {
19 this.Ado = ado;
20 }
21 }
三、扩展方法实现 还可以扩展很多功能 只有你想不到,没有...
1 /// <summary>
2 /// 包括扩展类
3 /// </summary>
4 public static class IncludeExtensions
5 {
6 /// <summary>
7 /// 然后包括
8 /// </summary>
9 /// <typeparam name="T"></typeparam>
10 /// <typeparam name="TPreviousProperty"></typeparam>
11 /// <param name="include">包括</param>
12 /// <returns></returns>
13 public static IInclude<T, TPreviousProperty> Visit<T, TPreviousProperty>(this IInclude<T, List<TPreviousProperty>> include) where TPreviousProperty : class, new()
14 {
15 return new IncludeProvider<T, TPreviousProperty>(include.Ado, include.QueryBuilder);
16 }
17
18 /// <summary>
19 /// 然后包括
20 /// </summary>
21 /// <typeparam name="T"></typeparam>
22 /// <typeparam name="TProperty"></typeparam>
23 /// <param name="include">包括</param>
24 /// <param name="expression">表达式</param>
25 /// <returns></returns>
26 public static IInclude<T, TProperty> ThenInclude<T, TPreviousProperty, TProperty>(this IInclude<T, List<TPreviousProperty>> include, Expression<Func<TPreviousProperty, TProperty>> expression) where TProperty : class, new()
27 {
28 return new IncludeProvider<T, TProperty>(include.Ado, include.QueryBuilder);
29 }
30
31 /// <summary>
32 /// 条件
33 /// </summary>
34 /// <typeparam name="T"></typeparam>
35 /// <typeparam name="TProperty"></typeparam>
36 /// <param name="include">包括</param>
37 /// <param name="expression">表达式</param>
38 /// <returns></returns>
39 public static IInclude<T, TProperty> Where<T, TProperty>(this IInclude<T, TProperty> include, Expression<Func<T, TProperty, bool>> expression) where TProperty : class, new()
40 {
41 var queryBuilder = include.QueryBuilder.IncludeInfos.Last().QueryBuilder;
42
43 queryBuilder.EntityDbMapping.Alias = expression.Parameters[0]?.Name;
44 include.QueryBuilder.IncludeInfos.Last().EntityDbMapping.Alias = expression.Parameters[1]?.Name;
45
46 var result = expression.ResolveSql(new ResolveSqlOptions()
47 {
48 DbType = include.Ado.DbOptions.DbType,
49 ResolveSqlType = ResolveSqlType.Where,
50 ParameterIndex = queryBuilder.DbParameters.Count + 1
51 });
52
53 queryBuilder.Where.Add(result.SqlString);
54 queryBuilder.DbParameters.AddRange(result.DbParameters);
55 return include;
56 }
57
58 /// <summary>
59 /// 排序
60 /// </summary>
61 /// <typeparam name="T"></typeparam>
62 /// <typeparam name="TProperty"></typeparam>
63 /// <param name="include">包括</param>
64 /// <param name="orderFields">排序字段</param>
65 /// <param name="orderByType">排序类型</param>
66 /// <returns></returns>
67 public static IInclude<T, TProperty> OrderBy<T, TProperty>(this IInclude<T, TProperty> include, List<string> orderFields, OrderByType orderByType = OrderByType.ASC) where TProperty : class, new()
68 {
69 var queryBuilder = include.QueryBuilder.IncludeInfos.Last().QueryBuilder;
70
71 queryBuilder.OrderBy.Add($"{string.Join(",", orderFields)} {orderByType}");
72 return include;
73 }
74
75 /// <summary>
76 /// 排序
77 /// </summary>
78 /// <typeparam name="T"></typeparam>
79 /// <typeparam name="TProperty"></typeparam>
80 /// <param name="include">包括</param>
81 /// <param name="expression">表达式</param>
82 /// <param name="orderByType">排序类型</param>
83 /// <returns></returns>
84 public static IInclude<T, TProperty> OrderBy<T, TProperty>(this IInclude<T, TProperty> include, Expression<Func<T, TProperty, object>> expression, OrderByType orderByType = OrderByType.ASC) where TProperty : class, new()
85 {
86 var queryBuilder = include.QueryBuilder.IncludeInfos.Last().QueryBuilder;
87
88 queryBuilder.EntityDbMapping.Alias = expression.Parameters[0]?.Name;
89 include.QueryBuilder.IncludeInfos.Last().EntityDbMapping.Alias = expression.Parameters[1]?.Name;
90
91 var result = expression.ResolveSql(new ResolveSqlOptions()
92 {
93 DbType = include.Ado.DbOptions.DbType,
94 ResolveSqlType = ResolveSqlType.OrderBy
95 });
96
97 queryBuilder.OrderBy.Add($"{result.SqlString} {orderByType}");
98 return include;
99 }
100
101 /// <summary>
102 /// 选择
103 /// </summary>
104 /// <typeparam name="T"></typeparam>
105 /// <typeparam name="TProperty"></typeparam>
106 /// <param name="include">包括</param>
107 /// <param name="expression">表达式</param>
108 /// <returns></returns>
109 public static IInclude<T, TProperty> Select<T, TProperty>(this IInclude<T, TProperty> include, Expression<Func<T, TProperty, object>> expression) where TProperty : class, new()
110 {
111 var queryBuilder = include.QueryBuilder.IncludeInfos.Last().QueryBuilder;
112
113 queryBuilder.EntityDbMapping.Alias = expression.Parameters[0]?.Name;
114 include.QueryBuilder.IncludeInfos.Last().EntityDbMapping.Alias = expression.Parameters[1]?.Name;
115
116 var result = expression.ResolveSql(new ResolveSqlOptions()
117 {
118 DbType = include.Ado.DbOptions.DbType,
119 ResolveSqlType = ResolveSqlType.NewAs
120 });
121
122 queryBuilder.Columns = result.SqlString;
123 queryBuilder.DbParameters.AddRange(result.DbParameters);
124 return include;
125 }
126
127 }
128 }
四、使用示例
1 var data = await db.Query<Category>().Include(a => a.Products).Visit().OrderBy((a1, a2) => a2.CreateTime, OrderByType.DESC).ToListAsync();
五、生成的SQL语句
SELECT a1.`CategoryId`,a1.`CategoryName`,a2.`ProductId`,a2.`CategoryId`,a2.`ProductCode`,a2.`ProductName`,a2.`DeleteMark`,a2.`CreateTime`,a2.`ModifyTime`,a2.`Custom1`,a2.`Custom2`,a2.`Custom3`,a2.`Custom4`,a2.`Custom5`,a2.`Custom6`,a2.`Custom7`,a2.`Custom8`,a2.`Custom9`,a2.`Custom10`,a2.`Custom11`,a2.`Custom12` FROM `Category` `a1`
INNER JOIN `Product` `a2` ON `a1`.`CategoryId` = `a2`.`CategoryId`
WHERE `a1`.`CategoryId` = @CategoryId
ORDER BY `a2`.`CreateTime` DESC
翻译
搜索
复制
自研ORM框架 实现类似EF Core Include 拆分查询 支持自定义条件、排序、选择的更多相关文章
- .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger
前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...
- 深入理解 EF Core:使用查询过滤器实现数据软删除
原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...
- EF Core 的关联查询
0 前言 本文会列举出 EF Core 关联查询的方法: 在第一.二.三节中,介绍的是 EF Core 的基本能力,在实体中配置好关系,即可使用,且其使用方式,与编程思维吻合,是本文推荐的方式. 第四 ...
- EF Core 使用编译查询提高性能
今天,我将向您展示这些EF Core中一个很酷的功能,通过使用显式编译的查询,提高查询性能. 不过在介绍具体内容之前,需要说明一点,EF Core已经对表达式的编译使用了缓存:当您的代码需要重用以前执 ...
- EF Core 2.0 已经支持自动生成父子关系表的实体
现在我们在SQL Server数据库中有Person表如下: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Cr ...
- EF core的原生SQL查询以及用EF core进行分页查询遇到的问题
在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异. 在EF6中我们用SqlQuery和Exe ...
- ORM框架学习之EF
首先推荐一篇很好的EF文章翻译,可以系统的学习一遍. <Entity Framework 6 Recipes>中文翻译系列 EF使用体会 优点: 可以省去Ado.net复杂的管道连接代码. ...
- EF Core 快速上手——EF Core 入门
EF Core 快速上手--EF Core 介绍 本章导航 从本书你能学到什么 对EF6.x 程序员的一些话 EF Core 概述 1.3.1 ORM框架的缺点 第一个EF Core应用 本文是对 ...
- EntityFramework Core 3.0查询
前言 随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询. 分组 我们知道在E ...
- Mego(2) - NET主流ORM框架分析
接上文我们测试了各个ORM框架的性能,大家可以很直观的看到各个ORM框架与原生的ADO.NET在境删改查的性能差异.这里和大家分享下我对ORM框架的理解及一些使用经验. ORM框架工作原理 典型ORM ...
随机推荐
- STM32F0单片机基于Hal库温控智能风扇
一.项目概述 设计采用STM32F0系列单片机做主控芯片,通过DHT11采集温湿度,将温度显示在OLED 屏幕上.根据温度的不同,利用STM32对风扇进行调速,总体硬件设计如下图所示 1.效果展示 2 ...
- 监控平台SkyWalking9入门实践
简便快速的完成对分布式系统的监控: 一.业务背景 微服务作为当前系统架构的主流选型,虽然可以应对复杂的业务场景,但是随着业务扩展,微服务架构本身的复杂度也会膨胀,对于一些核心的业务流程,其请求链路会涉 ...
- display:block 和display:inline-block的区别和用法
1).块状元素:(div,p,form,ul,ol,li) ,独占一行,默认情况width为100% 2).行内块状元素:(span,img,a),不会独占一行,相邻的元素一直排在同一行,排满了才会换 ...
- Java程序设计(五)作业
题目1:Lisa正在编写一个能够计算三科--数学.英语.程序设计基础--平均成绩(平均成绩=三科总成绩/3)和智育成绩(智育成绩=三科总成绩*0.7)的程序.由于两个成绩的获得都要先计算总成绩,因此她 ...
- Jquery关于checkbox选中第二次失效的问题。
$(".selector input[type='checkbox']").attr("checked",true); $(".selector in ...
- 【算法】基础DP
参考资料 背包九讲 一.线性DP 如果现在在状态 i 下,它上一步可能的状态是什么. 上一步不同的状态依赖于什么. 根据上面的分析,分析出状态和转移方程.注意:dp 不一定只有两维或者一维,一开始设计 ...
- JS前端防止F12扒取源码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Vue学习之--------消息订阅和发布、基础知识和实战应用(2022/8/24)
文章目录 1.基础知识 2.代码实例 2.1 main.js 2.2 School.vue 2.3 Student.vue 2.4 App.vue 3.全局事件总线通信改为消息的订阅和发布 3.1 核 ...
- offset新探索:双管齐下,加速大数据量查询
摘要:随着offset的增加,查询的时长也会越来越长.当offset达到百万级别的时候查询时长通常是业务所不能容忍的. 本文分享自华为云社区<offset新探索:双管齐下,加速大数据量查询> ...
- Debian安装 WineHQ 安装包
https://wiki.winehq.org/Debian_zhcn WineHQ 源仓库的密钥于 2018-12-19 改变过.如果您在此之前下载添加过该密钥,您需要重新下载和添加新的密钥并运行 ...