有关 C#多表查询学习

导言

在后端多表查询这一块还是不太会,主要是在左连接和innerjoin这块,上课混的时间总是要还回来的...主要是举后端的几个案例来相应学习查询的知识。所用到的例子是自己搞的C#后端,数据库用的是若依的表,有些有些微改变。

多表查询概述

1. 内连接(INNER JOIN)
  • 定义:内连接只返回两个表中符合连接条件的匹配记录。如果其中一个表没有匹配的记录,则不会包含在结果中。
  • 用途:适用于需要两个表中的共同数据的场景。
2. 外连接(OUTER JOIN)

外连接用于返回一个表中的所有记录,并根据条件获取另一个表中匹配的记录。外连接分为三种:左连接(LEFT JOIN)、右连接(RIGHT JOIN)和全连接(FULL JOIN)。

a. 左连接(LEFT JOIN 或 LEFT OUTER JOIN)
  • 定义:左连接返回左表中的所有记录,不论右表中是否有匹配的记录。如果右表中没有匹配的记录,则返回 NULL。
  • 用途:适用于需要左表的所有数据,而右表的数据是可选的场景。
b. 右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)
  • 定义:右连接返回右表中的所有记录,不论左表中是否有匹配的记录。如果左表中没有匹配的记录,则返回 NULL。
  • 用途:适用于需要右表的所有数据,而左表的数据是可选的场景。
c. 全连接(FULL JOIN 或 FULL OUTER JOIN)
  • 定义:全连接返回两个表中的所有记录。包括左表和右表中不匹配的数据,如果某一表中没有匹配的记录,则返回 NULL。
  • 用途:适用于需要获取左表和右表的所有记录,包括匹配和不匹配的数据。

举例

内连举例:
表:

用户角色表:

角色菜单表:

菜单表:

查询语句:
            
            //根据用户id返回用户所拥有的id
            //根据用户信息查所拥有的角色,
            //根据所拥有的角色查所拥有的菜单,注意去重
            //拿用户的菜单信息,返回
            var source = Db.Queryable<Sys_UserRole, Sys_Role_Menu,Sys_Menu>((a, b, c) => new object[]{
                JoinType.Inner,a.UserID == userInfo.UserID,
                JoinType.Inner,a.RoleID == b.RoleId,
                JoinType.Inner,b.MenuId == c.ID

            })//查到多余(不属于所查询用户的菜单)原因:筛选条件少了 b.MenuId == c.ID,猜测是内联和外联没筛完全数据
             .Where((a,b,c) =>(c.menuType == 'M' || c.menuType == 'C')&& b.MenuId == c.ID)
            .Select((a,b,c) => new Sys_Menu
            {
                ID = c.ID,
                name = c.name,
                ....
            })
            .Distinct()
            .ToList();

按顺序依次连接角色用户,角色菜单,菜单表,每个表之间都有一样的字段进行连接,但不知道为什么。这个语句在没有 b.MenuId == c.ID限制的话会查到多余的数据,由于不知道如何排查,故只能做些猜测,如果有大佬知道的话可以指导一下。

外连:左连接举例
表:

设备表;

关系表:

部门表:

用户表:

查询语句:
            //查设备VM,包括所属部门,正在使用的用户
            var source = Db.Queryable<Base_Equipment, Sys_DataRelation, Base_Dept, Sys_Users>((a, b, c,d) => new object[] {
                JoinType.Inner,a.ID == b.Form,
                JoinType.Inner,b.To == c.ID,
                JoinType.Left,a.UsingUserID == d.UserID,
            })
            .WhereIF(!string.IsNullOrEmpty(parm.QueryText), (a, b, c,d) => a.EquipNo.Contains(parm.QueryText) || a.EquipName.Contains(parm.QueryText))
            .Select((a, b, c,d) => new EquipmentVM
            {
                ID = a.ID,
                EquipNo = a.EquipNo,
                EquipName = a.EquipName,
                EquipmentStatus = a.EquipmentStatus,
                Remark = a.Remark,
                DeptName = c.DeptName,
                UsingUser = string.IsNullOrEmpty(a.UsingUserID) ? d.UserName:null,
                CreateTime = a.CreateTime,
                UpdateTime = a.UpdateTime,
                CreateID = a.CreateID,
                CreateName = a.CreateName,
                UpdateID = a.UpdateID,
                UpdateName = a.UpdateName
            })
            .MergeTable();
具体介绍三条连接语句:
JoinType.Inner, a.ID == b.Form,
JoinType.Inner, b.To == c.ID,

这两条语句使用内连接,意味着只返回在 Base_EquipmentSys_DataRelation 之间、以及 Sys_DataRelationBase_Dept 之间存在匹配记录的结果。如果某一表没有对应的匹配记录,则相关的设备信息将不会出现在最终结果中。

JoinType.Left, a.UsingUserID == d.UserID,

这里使用左连接,意味着即使在 Base_Equipment 表中的 UsingUserIDSys_Users 表中的 UserID 之间没有匹配的记录,设备信息仍会被返回,UsingUser 将会是 null。这通常用于需要保留主表(在此为设备表)所有记录的情况下,同时获取相关表的可选信息。

使用内连/外连的场合

  • 内连接的使用场景

    • 确保数据完整性: 当你只希望获取两张表中匹配的数据时,使用内连接非常合适。例如,查询某个设备时,你想确认它是否有对应的部门和关系。
    • 多表联合查询时需要的主数据: 如果业务逻辑要求必须存在相关记录才能显示设备数据(如设备必须有关联部门和关系),那么内连接是理想的选择。
  • 外连接的使用场景

    • 保留主表的记录: 当你需要从主表中获取所有记录,而不管它们在其他表中是否有匹配项时,使用外连接(尤其是左连接)是适合的。例如,在设备查询中,即使没有正在使用的用户,你仍希望显示所有设备的信息。
    • 可选关联数据: 当某些关联数据是可选的,而不是必须的,比如可能某个设备当前没有分配用户,依然需要显示设备的基础信息,则适合使用左连接。

多表查询的建议

1.明确要查的数据,是要都对应,还是要保留主表,附表可以为空,选择适合的连接方式。

2.只保留关键的连接语句,减少不必要的连接语句。有多余的连接语句会产生重复的数据。

3.可适当使用去重,上面举例的.Distinct()。

4.如果查询条件过于复杂,可分多次查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/892552.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么SSH协议是安全的?

SSH的传输层协议&#xff08;Transport Layer Protocol&#xff09;和用户鉴权协议&#xff08;Authentication Protocol&#xff09;确保数据的传输安全&#xff0c;这里只介绍传输层协议&#xff0c;是SSH协议的基础。 本文针对SSH2协议。 1、客户端连接服务器 服务器默认…

相似扇形问题

甘肃临夏砖雕是一种历史悠久的古建筑装饰艺术&#xff0c;是第一批国家级非物质文化遗产,如图1是一块扇面形的临夏砖雕作品&#xff0c;它的部分设计图如图2&#xff0c;其中扇形OBC和扇形OAD有相同的圆心O&#xff0c;且圆心角O100度&#xff0c;若OA120cm, OB60cm &#xff0…

9.22前缀和

当我们计算n个数的和的时候&#xff0c;往往会采用循环操作&#xff0c;但是当我们要多次进行询问n个数之和时&#xff0c;如果采用多次循环&#xff0c;时间复杂度会升高&#xff0c;所以我们采用前缀和来解决多次询问时的求和 1.一维前缀和 提公因式&#xff0c;用分配律&am…

2024 kali系统2024版本,可视化界面汉化教程(需要命令行更改),英文版切换为中文版,基于Debian创建的kali虚拟机

我的界面如下所示 1. 安装 locales sudo apt install locales 2. 生成中文语言环境 sudo locale-gen zh_CN.UTF-8 如果你希望安装繁体中文&#xff0c;可以加入&#xff1a; sudo locale-gen zh_TW.UTF-8 3. 修改 /etc/default/locale 文件 确保有以下内容 LANGzh_CN.UT…

【优选算法】——双指针(下篇)!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~ &#x1f525;系列专栏&#xff1a;C刷题算法总结 &#x1f516;克心守己&#xff0c;律己则安 目录 1、有效三角形的个数 2、查找总价值为目标值的两个商品 3、三数之和 4、四数之和 5、完结散花 1、有…

react18中实现简易增删改查useReducer搭配useContext的高级用法

useReducer和useContext前面有单独介绍过&#xff0c;上手不难&#xff0c;现在我们把这两个api结合起来使用&#xff0c;该怎么用&#xff1f;还是结合之前的简易增删改查的demo&#xff0c;熟悉vue的应该可以看出&#xff0c;useReducer类似于vuex&#xff0c;useContext类似…

智慧供排水管网在线监测为城市安全保驾护航

一、方案背景 随着城市化进程的不断推进&#xff0c;城市供排水管网作为城市基础设施的关键组成部分&#xff0c;其安全稳定的运行对于确保城市居民的日常生活、工业生产活动以及整个生态环境的健康具有至关重要的作用。近年来&#xff0c;由于各种原因&#xff0c;城市供排水管…

Springboot整合knife4j生成文档

前言 在开发过程中&#xff0c;接口文档是很重要的内容&#xff0c;用于前端对接口的联调&#xff0c;也用于给其他方使用。但是手写相对比较麻烦。 当然也有swagger之类的&#xff0c;但是界面没有那么友好。 官网&#xff1a; 整合步骤 整合依赖 需要根据版本进行&…

深入了解Spring重试组件spring-retry

在我们的项目中&#xff0c;为了提高程序的健壮性&#xff0c;很多时候都需要有重试机制进行兜底&#xff0c;最多就场景就比如调用远程的服务&#xff0c;调用中间件服务等&#xff0c;因为网络是不稳定的&#xff0c;所以在进行远程调用的时候偶尔会产生超时的异常&#xff0…

python之socket网络编程

华子目录 引言什么是socketsocket套接字类型TCP和UDP socket服务端核心组件1.创建socket对象2.绑定地址和端口3.监听连接4.接受连接5.接受client端消息client_sock.revc(1024)6.发送响应给client端6.1client_sock.send()6.2client_sock.sendall() 7.关闭client端连接8.关闭serv…

flutter 使用三方/自家字体

将字体放入assets/fonts下 在pubspec.yaml文件中flutter下添加如下代码&#xff1a; flutter:fonts:- family: MyCustomFontfonts:- asset: assets/fonts/MyCustomFont.ttf 在flutter Text widget中使用字体 import package:flutter/material.dart;void main() > runApp(…

PyQt 入门教程(3)基础知识 | 3.2、加载资源文件

文章目录 一、加载资源文件1、PyQt5加载资源文件2、PyQt6加载资源文件 一、加载资源文件 常见的资源文件有图像与图标&#xff0c;下面分别介绍下加载资源文件的常用方法 1、PyQt5加载资源文件 2、PyQt6加载资源文件 PyQt6版本暂时没有提供pyrcc工具&#xff0c;下面介绍下在不…

js中map,filter,find,foreach的用法介绍

js中map&#xff0c;filter&#xff0c;find&#xff0c;foreach的用法介绍 在 JavaScript 中&#xff0c;数组提供了一些常用的迭代方法&#xff0c;如 map、filter、find 和 forEach&#xff0c;这些方法允许你对数组中的每个元素进行操作&#xff0c;下面是它们的用法和区别…

抖音解压视频素材宝库

在快节奏的生活中&#xff0c;解压视频成为抖音上的热门内容类型&#xff0c;想要制作出精彩的解压视频&#xff0c;优质素材必不可少。今天&#xff0c;为大家推荐几个超棒的抖音解压视频素材网站&#xff0c;让你的创作之路轻松无忧&#xff01; 蛙学网 作为国内知名的短视频…

【Canvas与化学】铁元素图标

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>铁元素图标Draft1</title><style type"text/css"…

域渗透AD 示例场景漏洞 Kerberos Bronze Bit 【CVE-2020-17049】漏洞

背景 漏洞原理 漏洞复现 约束性委派攻击绕过 基于资源的约束性委派攻击绕过 漏洞预防和修复 背景 Kerberos Bronze Bit (CVE-2020-17049) 漏洞是国外安全公司 Netspi 安全研究员Jake Karnes 发现的一个Kerberos安全功能绕过漏洞。该漏洞存在的原因在于KDC在确定Kerberos服…

YoloV10改进:Block改进|使用ContextAggregation模块改善C2f模块|即插即用

摘要 在计算机视觉领域&#xff0c;目标检测与实例分割任务一直是研究的热点。YoloV10作为目标检测领域的佼佼者&#xff0c;凭借其出色的性能和效率赢得了广泛的认可。然而&#xff0c;随着技术的不断进步&#xff0c;如何进一步提升YoloV10的性能成为了我们追求的目标。近期…

Java爬虫之使用Selenium WebDriver 爬取数据

这里写自定义目录标题 Selenium WebDriver简介一、安装部署二、Java项目中使用1.引入依赖2.示例代码 三、WebDriver使用说明1.WebDriver定位器2.常用操作3.使用 cookie4.键盘与鼠标操作 Selenium WebDriver简介 Selenium WebDriver 是一种用于自动化测试 Web 应用程序的工具。…

【实战指南】Vue.js 介绍组件数据绑定路由构建高效前端应用

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

ollama + fastgpt+m3e本地部署

ollama fastgptm3e本地部署 开启WSL更新wsl安装ubuntu docker下载修改docker镜像源开启WSL integration 安装fastgpt先创建一个文件夹来放置一些配置文件用命令下载fastgpt配置文件用命令下载docker的部署文件 启动容器M3E下载ollama下载oneapi配置登录oneapi配置ollama渠道配…