EFCore多数据库合并查询分页

参照:二个表的数据 如何做分页?_两个表排序分页_深圳市热心市民市民的博客-CSDN博客

基本情况介绍:由于系统迭代,部分收藏表在老系统的数据库,部分在新api接口的数据库,现在有一个需求是在个人中心展示用户收藏的数据,按照收藏时间倒序排列,因为在APP端实际上就算瀑布流分页。

主体思路:通过将两个表通过条件筛选形成IQuerable,再通过Union联结,做的分页,再通过ToList()加载到内存里

query1.Union(query2).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

但是经过尝试后,报错:Cannot use multiple DbContext instances within a single query execution。在一个查询里只能使用一个数据库上下文实例。因为来自两个不同的数据库所以query1和query2我们使用了两个不同的 DBContext,配置了不同的数据库连接。结果就出现了上述的报错。转念又想有没有可能在一个负责管理实体对象的上下文中设置多个数据库那不就可以了吗?但是查阅资料,发现并不能实现。因为当存在多个数据库在 DbContext里的 DbSet没办法指定它属于哪个数据库。简而言之,就是一个 DBContext只能对应一个数据库

所以思路调整为从两个 DBContext里查找出结果集(ToList()加载到内存里),再将结果集合并后再做分页,这就涉及到怎么取数据能得到准确的结果还能使得查询效率最大化?假设我们是按照创建时间逆序,每页10条:

这里有一个容易犯错的思路:假设是第一页,先从A表里取10里取5条,再从B表里取5条,合并后再按照时间排序输出。这样做最大的问题是,没办法保证数据的准确性。因为极端一点可能最新的10条数据都来自B表,这样取是没办法保证数据准确性的。

以上错误的做法也给了我们参考意义,那各取多少条就能保证数据是准确的呢?答案是 pageNumber*pageSize为什么呢?以第一页为例,假设每页10条,我从A表里取10条,再从B表里取10条,从合并后的20条里找出最新的10条,这是肯定合理的,它能涵盖这页数据全部来自其中一张表的情况。以此类推,第二页:各取20条;第三页:各取30条...以此类推。很容易发现问题,就是约到后面的页码,我们要取得数据越多。基本上是线性增加的,那就意味着到了后面的页码会出现我们之前不愿见到的局面:我们把大量的结果集都加载到了内存里,再进行合并排序分页。

参照的文章给了我们思路。因为我们分页基本上是在排序后进行的,所以我们每次分页的最后一条数据,可以作为下一页数据的的筛选判断条件。以我们文中例子,第一页第10条数据的创建时间一定是大于第二页的数据的。我们就可以在调用接口时除了我们的页码参数,把前一页码数据最后一条的创建时间也带上当作参数传入。结果是

var result1 = dbContext1.Colections.where(s=>s.CreateTime< timeParm).OrderByDescending(s=>s.CreateTime).Take(pageSize).ToList();
var result2 =dbContext2.Colections.where(s=>s.CreateTime< timeParm).OrderByDescending(s=>s.CreateTime).Take(pageSize).ToList();

仅仅只需要每次各从结果集取出pageSize条,甚至不需要pageNum的参数就能实现我们需要的效果。另外它还有个隐藏性能福利:我们通过where的筛选实现了 Skip((pageNumber - 1) * pageSize)的效果,性能会更高。每次取出加载到内存的结果集都很小,实现了我们预期的效果。

EFCore多数据库合并查询分页的更多相关文章

  1. oracle 基础SQL语句 多表查询 子查询 分页查询 合并查询 分组查询 group by having order by

    select语句学习 . 创建表 create table user(user varchar2(20), id int); . 查看执行某条命令花费的时间 set timing on: . 查看表的 ...

  2. .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...

  3. 基于Mysql数据库的SSM分页查询

    前言: Hello,本Y又来了,"分页"在我们使用软件的过程中是一个很常见的场景,比如博客园对于每个博主的博客都进行了分页展示.可以简单清晰的展示数据,防止一下子将过多的数据展现给 ...

  4. mysql表查询、多表查询(增强查询的使用)子查询、合并查询,外连接,mysql5种约束,自增长

    一.查询加强 1.在mysql中,日期类型可以直接比较,需要注意格式 2.%:表示0到多个字符, _:表示单个字符 exp:显示第二个字符为大写O的所有员工的姓名和工资 select  name fr ...

  5. TODO:数据库优化之分页

    TODO:数据库优化之分页 本文的例子是以MongoDB数据库为准,其它数据库各位也可以举一反三进行优化. 在MongoDB中分页使用 a.skip(n)跳过前n个匹配的文档: b.limit(m)返 ...

  6. 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  7. SQL多表合并查询结果

    两表合并查询,并同时展示及分页SELECT a.* FROM ( ( SELECT punycode, `domain`, 'Success' AS state, add_time, AS refun ...

  8. Oracle数据库的SQL分页模板

    在系统开发过程中,需要对数据进行查询,大部分情况下从数据库中查询的数据量比较大,在系统页面无法全部显示,而且查询全部的数据会影响系统的反应速度,需要对所查询的数据进行分页的查询操作,以此减轻系统的压力 ...

  9. mysql数据库管理工具sqlyog在首选项里可以设置默认查询分页条数和字体,改写关键字大小写

    sqlyog设置一直习惯用sqlyog来管理mysql数据库,但有三个地方用得不是很爽:1.默认查询条数只有1000条经常需要勾选掉重新查询.2.自动替换关键字大小写,有时候字段名为关键字的搞成大写的 ...

  10. [R语言]foreach和doParallel包实现多个数据库同时查询

    R语言在进行数据库查询时,每执行一条语句,都会阻塞.直到查询语句返回结果之后,才会进行下一条语句. 为了能够实现同时对多个数据库进行查询,以节省顺序执行下来的时间,首先考虑通过多线程来进行数据库查询. ...

随机推荐

  1. Mac使用docker安装Doris

    一.编译源码 (1)拉取编译镜像docker pull apache/incubator-doris:build-env-1.2 (2)Mac电脑上拉取源码git clone https://gith ...

  2. 记一次CUDA报错

    报错内容:CUDA error: device-side assert triggered 原因:使用ResNet50训练时使用了pretrained=True的模型,但实际类别数classes远超过 ...

  3. MybatisPlus - [01] 概述

    MybatisPlus可以节省我们大量工作时间,所有的CURD代码它都可以自动化完成! 一.是什么   MyBatis-Plus(简称MP)是一个基于MyBatis的增强工具,其设计目的是在不改变My ...

  4. 读论文-顺序推荐系统_挑战、进展和前景(Sequential recommender systems_ challenges, progress and prospects)

    前言 今天读的论文为一篇于2019年发表的论文,是关于顺序推荐系统(Sequential Recommender Systems,SRSs)的研究,作者对SRSs的挑战.进展和前景进行了系统综述. 要 ...

  5. linux服务问题传文件连不上问题远程问题等

    通过iptables相关命令实现防火墙的打开和关闭 1.首先可以在打开的终端使用iptables --help查看帮助使用命令: 2.查看防火墙状态:service iptables status(此 ...

  6. C++17 Filesystem 实用教程

    点击查看代码 C++17 标准带来了 std::filesystem库, 提供了强大的工具来处理文件路径, 目录以及其他与文件系统相关的操作. 这篇文章适合 C++ 初学者以及希望掌握 C++17 新 ...

  7. 震惊!Manus邀请码炒到5万元一个!附免费获取Manus邀请码两种方式

    在AI技术蓬勃发展的当下,一款名为Manus的产品掀起了行业巨浪.本文将深入剖析这款全球首款通用AI智能体,从它的惊艳亮相.独特功能,到其性能突破.模式限制,以及在AI领域的深远意义,全方位带大家了解 ...

  8. Oracle客户端中文显示问号乱码问题

    Oracle显示中文显示??乱码 问题如下图 解决方法 打开Oracle客户端,新建一个SQL Window 输入select userenv('language') from dual 复制搜索到的 ...

  9. 最新版 Proteus 8.15 Professional 图文安装教程(附安装包)

    前言 大家好,我是梁国庆. Proteus 是世界上唯一将电路仿真软件.PCB设计软件和虚拟模型仿真软件三合一的设计平台. 本篇博主将手把手带领大家安装最新版 Proteus 8.15. 若图片加载超 ...

  10. 扩展知识:vscode配置easyx

    扩展知识:vscode配置easyx 前言 ‍ 因为个人用习惯了vscode,对于visual studio的操作只能说相当程度上很不适应,因此,我打算经历一番配置,让vscode可以配置上easyx ...