首页 > 数据库 >EFCore多数据库合并查询分页

EFCore多数据库合并查询分页

时间:2023-08-21 19:44:16浏览次数:50  
标签:10 分页 pageSize ToList 数据库 EFCore 数据

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)的效果,性能会更高。每次取出加载到内存的结果集都很小,实现了我们预期的效果。

标签:10,分页,pageSize,ToList,数据库,EFCore,数据
From: https://www.cnblogs.com/summerZoo/p/17646904.html

相关文章

  • RISC-V公测平台发布 · 数据库在RISC-V服务器上的适配评估
    前言上一期讲到YCSB在RISC-V服务器上对MySQL进行性能测试(RISC-V公测平台发布·使用YCSB测试SG2042上的MySQL性能),在这一期文章中,我们继续深入讨论RISC-V+数据库的应用。本期就继续利用HS-2平台来测试数据库软件在RISC-V服务器上的兼容性。参与此次实验的数据库如下:RedisMongo......
  • Mysql数据库2
     事务的定义:事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。事务的特性ACID:原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。......
  • 深入理解数据库事务:确保数据完整性与一致性
    前言在现代信息系统中,数据是至关重要的资产之一。作为一名后端开发人员,与数据库的交道必不可少,为了确保数据的完整性、一致性和可靠性,数据库引入了事务的概念。本次将带您深入了解数据库事务的重要性、特性以及如何在应用程序中正确地使用事务来维护数据的稳定性。什么是数据库......
  • Apache DolphinScheduler 支持使用 OceanBase 作为元数据库啦!
    DolphinScheduler是一个开源的分布式任务调度系统,拥有分布式架构、多任务类型、可视化操作、分布式调度和高可用等特性,适用于大规模分布式任务调度的场景。目前DolphinScheduler支持的元数据库有Mysql、PostgreSQL、H2,如果在业务中需要更好的性能和扩展性,可以在DolphinScheduler......
  • mysql登陆数据库报错Segmentation fault (核心已转储)的解决办法
     转自:https://bbs.cnbugs.com/read-43-1.html今天在登陆新安装好的数据库报如下错误: [root@lnmp~]#mysql-uroot-pEnterpassword:WelcometotheMySQLmonitor.Commandsendwith;or\g.YourMySQLconnectionidis13Serverversion:8.0.21 Copyright(c......
  • 数据库基础
    数据库简介数据库定义与概念数据库是一种存储、组织和管理大量数据的软件工具。它能够存储各种类型的数据,包括文本、图像、视频、音频等,并且可以方便地对其进行读取、写入和更新等操作。数据库的概念可以追溯到二十世纪早期,最早的数据库是文件系统,后来逐渐演化为关系型数据库......
  • 达梦数据库 dexp和dimp的使用
    介绍Oracle中备份还原数据有exp和imp,而达梦数据库也有dexp和dimp命令,用来备份还原达梦的数据。操作类型逻辑使用场景dexp和dimp既可以用于服务端中,又能够在客户端使用。备注,此备份还原方案是逻辑操作,在少量数据的情况下,性能足够,一旦数据量过大,则备份时间极长。同步方式达梦数据库支......
  • 一次分页慢查询导致的事故处理过程
    事故背景这次事故也是我们组里遇到的一次关于分页慢查询的典型例子,通过这篇文章,你可以很清晰的跟随我们还原事故现场,以及每一步遇到问题做出的调整和改动。事故问题现场16:00收到同事反馈,融合系统分⻚查询可⽤率降低16:05查询接⼝UMP监控,发现接⼝TP99异常彪⾼打开机器监控,发现⼏......
  • 直播系统源码,实现上滑加载分页(触底加载)
    直播系统源码,实现上滑加载分页(触底加载) //依据分类查询图书  publicfunctionquery_book_by_classid(){    $token=input('token');    $class_id=input('class_id');    $page=input('page');//起始行    $per_page=input('per_page');//......
  • 查询SQL SERVER数据库会话阻塞
    SELECT[session_id],[blocking_session_id]AS'正在阻塞其他会话的会话ID',DB_NAME([database_id])AS'数据库名称',[request_id],[cpu_time],[start_time]AS'开始时间',[status]AS'状态',[command]AS'命令',......