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 拆分查询 支持自定义条件、排序、选择的更多相关文章

  1. .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger

    前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...

  2. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  3. EF Core 的关联查询

    0 前言 本文会列举出 EF Core 关联查询的方法: 在第一.二.三节中,介绍的是 EF Core 的基本能力,在实体中配置好关系,即可使用,且其使用方式,与编程思维吻合,是本文推荐的方式. 第四 ...

  4. EF Core 使用编译查询提高性能

    今天,我将向您展示这些EF Core中一个很酷的功能,通过使用显式编译的查询,提高查询性能. 不过在介绍具体内容之前,需要说明一点,EF Core已经对表达式的编译使用了缓存:当您的代码需要重用以前执 ...

  5. EF Core 2.0 已经支持自动生成父子关系表的实体

    现在我们在SQL Server数据库中有Person表如下: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Cr ...

  6. EF core的原生SQL查询以及用EF core进行分页查询遇到的问题

    在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异. 在EF6中我们用SqlQuery和Exe ...

  7. ORM框架学习之EF

    首先推荐一篇很好的EF文章翻译,可以系统的学习一遍. <Entity Framework 6 Recipes>中文翻译系列 EF使用体会 优点: 可以省去Ado.net复杂的管道连接代码. ...

  8. EF Core 快速上手——EF Core 入门

    EF Core 快速上手--EF Core 介绍 本章导航 从本书你能学到什么 对EF6.x 程序员的一些话 EF Core 概述 1.3.1 ORM框架的缺点 第一个EF Core应用   本文是对 ...

  9. EntityFramework Core 3.0查询

    前言 随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询. 分组 我们知道在E ...

  10. Mego(2) - NET主流ORM框架分析

    接上文我们测试了各个ORM框架的性能,大家可以很直观的看到各个ORM框架与原生的ADO.NET在境删改查的性能差异.这里和大家分享下我对ORM框架的理解及一些使用经验. ORM框架工作原理 典型ORM ...

随机推荐

  1. 适合生产制造企业用的ERP系统有哪些?

    什么叫适合?匹配很重要!同是生产制造企业,规模不同.行业不同.发展阶段不同.生产模式不同.管理理念不同,适用的ERP自然也不同.不同规模的企业选用不同的系统,如过你是大型企业,业务管理都比较标准规范, ...

  2. 我操作MySQL的惊险一幕

    背景 前几天因工作需要,组长给我安排了一个数据清洗的任务. 任务:把 A 表的数据洗到 B 表. 我的第一反应,什么是「洗」?洗数据是什么?洗钱我倒是知道. 不过我不能慌啊,于是问了问组长. 我:组长 ...

  3. css自定义会话框

    效果图图下: HTML代码: <div style="background-color: transparent; border: 1px #DDDDDD solid; width: ...

  4. POJ3342 Party at Hali-Bula(树形DP)

    dp[u][0]表示不选u时在以u为根的子树中最大人数,dp[u][1]则是选了u后的最大人数: f[u][0]表示不选u时的唯一性,f[u][1]是选了u后的唯一性,值为1代表唯一,0代表不唯一. ...

  5. 驱动开发:内核取ntoskrnl模块基地址

    模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程 ...

  6. Spring Ioc容器xml配置

    Spring Ioc容器xml配置基本结构: <?xml version="1.0" encoding="UTF-8"?> <beans xm ...

  7. 驱动开发:内核枚举LoadImage映像回调

    在笔者之前的文章<驱动开发:内核特征码搜索函数封装>中我们封装实现了特征码定位功能,本章将继续使用该功能,本次我们需要枚举内核LoadImage映像回调,在Win64环境下我们可以设置一个 ...

  8. 如何用webgl(three.js)搭建一个3D库房,3D仓库,3D码头,3D集装箱可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

  9. ThreadPoolExecutor BlockingQueue讲解

    有四种常用阻塞队列策略: 1.直接拒绝:(Direct Handoffs) 一个好的工作队列应该是不缓存任务,而是直接交给线程处理,就如SynchronousQueue一样.一个任务将会入队失败,如果 ...

  10. Pthread 并发编程(一)——深入剖析线程基本元素和状态

    Pthread 并发编程(一)--深入剖析线程基本元素和状态 前言 在本篇文章当中讲主要给大家介绍 pthread 并发编程当中关于线程的基础概念,并且深入剖析进程的相关属性和设置,以及线程在内存当中 ...