EF5.x Code First 一对多关联条件查询,Contains,Any,All

背景

通过多个部门id获取所有用户,部门和用户是多对多。

已知部门id,获取该部门包括该部门下的所有子部门的所有用户。

关系如下:

public class Entity:IEntity{public Guid Id { get; set; }public string CreateUser { get; set; }public DateTime CreateTime { get; set; }public string ModifyUser { get; set; }public DateTime? ModifyTime { get; set; }[Timestamp]public Byte[] RowVersion { get; set; }}
//组织架构
public class WMS_Org : Entity{public WMS_Org() { }public string OrgName { get; set; }public string OrgDesc { get; set; }public int OrgOrder { get; set; }public string OrgFatherId { get; set; }public virtual ICollection<WMS_OrgUser> OrgUserIds { get; set; }}
//用户public class WMS_User : Entity{public WMS_User() { }public string UserName { get; set; }public string NickName { get; set; }public string UserPwd { get; set; }public string Sex { get; set; }public string Phone { get; set; }public string Email { get; set; }public string QQ { get; set; }public string Address { get; set; }public string Remark { get; set; }public virtual ICollection<WMS_OrgUser> UserOrgIds { get; set; }}
//组织架构和用户的关联
public class WMS_OrgUser : Entity{public WMS_OrgUser() { }public Guid OrgId { get; set; }[ForeignKey("OrgId")]public virtual WMS_Org Org { get; set; }public Guid UserId { get; set; }[ForeignKey("UserId")]public virtual WMS_User User { get; set; }}
已知组织的id

如上图,我单击0100组织架构,要获取该组织架构下的所有用户,首先由于用户是挂载到每个节点上的,所有需要事先遍历获取所有的子节点获取节点的id

放到Guid[]数组里

提交后台查询
//DBSET=DbSet<WMS_User>,ids=Guid[] ids参数
//第一种方式All
DBSET.Where(p => p.UserOrgIds.All(o=>ids.Contains(o.OrgId)));//第二种方式Any
DBSET.Where(p => p.UserOrgIds.Any(o=>ids.Contains(o.OrgId)));

注意EF采用Contains构造in的sql语句

很直观的可以看出两个区别,一个是All,一个Any,那么产生的sql有什么区别呢?

//All,EF产生的是inner Join
SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[UserName] AS [UserName], 
[Extent1].[NickName] AS [NickName], 
[Extent1].[UserPwd] AS [UserPwd], 
[Extent1].[Sex] AS [Sex], 
[Extent1].[Phone] AS [Phone], 
[Extent1].[Email] AS [Email], 
[Extent1].[QQ] AS [QQ], 
[Extent1].[Address] AS [Address], 
[Extent1].[Remark] AS [Remark], 
[Extent1].[Disable] AS [Disable], 
[Extent1].[CreateUser] AS [CreateUser], 
[Extent1].[CreateTime] AS [CreateTime], 
[Extent1].[ModifyUser] AS [ModifyUser], 
[Extent1].[ModifyTime] AS [ModifyTime], 
[Extent1].[RowVersion] AS [RowVersion]
FROM [dbo].[WMS_User] AS [Extent1]
WHERE NOT EXISTS (
SELECT 1 AS [C1]
FROM [dbo].[WMS_OrgUser] AS [Extent2]
WHERE ([Extent1].[Id] = [Extent2].[UserId])
AND (
(
NOT (
[Extent2].[OrgId] IN (CAST('4e108b91-be3c-4cf4-a074-3767b9b8c7dc' AS UNIQUEIDENTIFIER), 
CAST('1cc15f8c-3758-47d3-862a-5287ab5d0651' AS UNIQUEIDENTIFIER), 
CAST('e1bf6f5a-800a-4fd4-9309-576c1d84ba2f' AS UNIQUEIDENTIFIER), 
CAST('a436b8a9-4b3a-4bf9-bbdd-839571e03915' AS UNIQUEIDENTIFIER), 
CAST('b0d6aead-e72f-4fd5-b2cd-e575454d3a4c' AS UNIQUEIDENTIFIER))
)
)
OR (
CASE 
WHEN (
[Extent2].[OrgId] IN (
CAST('4e108b91-be3c-4cf4-a074-3767b9b8c7dc' AS UNIQUEIDENTIFIER), 
CAST('1cc15f8c-3758-47d3-862a-5287ab5d0651' AS UNIQUEIDENTIFIER), 
CAST('e1bf6f5a-800a-4fd4-9309-576c1d84ba2f' AS UNIQUEIDENTIFIER), 
CAST('a436b8a9-4b3a-4bf9-bbdd-839571e03915' AS UNIQUEIDENTIFIER), 
CAST('b0d6aead-e72f-4fd5-b2cd-e575454d3a4c' AS UNIQUEIDENTIFIER))
) THEN CAST(1 AS BIT)
WHEN (
NOT (
[Extent2].[OrgId] IN (
CAST('4e108b91-be3c-4cf4-a074-3767b9b8c7dc' AS UNIQUEIDENTIFIER), 
CAST('1cc15f8c-3758-47d3-862a-5287ab5d0651' AS UNIQUEIDENTIFIER), 
CAST('e1bf6f5a-800a-4fd4-9309-576c1d84ba2f' AS UNIQUEIDENTIFIER), 
CAST('a436b8a9-4b3a-4bf9-bbdd-839571e03915' AS UNIQUEIDENTIFIER), 
CAST('b0d6aead-e72f-4fd5-b2cd-e575454d3a4c' AS UNIQUEIDENTIFIER))
)
) THEN CAST(0 AS BIT)
END IS NULL
)
)
)
//Any方式,EF生成的Exists
SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[UserName] AS [UserName], 
[Extent1].[NickName] AS [NickName], 
[Extent1].[UserPwd] AS [UserPwd], 
[Extent1].[Sex] AS [Sex], 
[Extent1].[Phone] AS [Phone], 
[Extent1].[Email] AS [Email], 
[Extent1].[QQ] AS [QQ], 
[Extent1].[Address] AS [Address], 
[Extent1].[Remark] AS [Remark], 
[Extent1].[CreateUser] AS [CreateUser], 
[Extent1].[CreateTime] AS [CreateTime], 
[Extent1].[ModifyUser] AS [ModifyUser], 
[Extent1].[ModifyTime] AS [ModifyTime], 
[Extent1].[RowVersion] AS [RowVersion]
FROM [dbo].[WMS_User] AS [Extent1]
WHERE  EXISTS (SELECT 1 AS [C1]FROM [dbo].[WMS_OrgUser] AS [Extent2]WHERE ([Extent1].[Id] = [Extent2].[UserId]) AND ([Extent2].[OrgId] IN (cast('bd3c010c-476f-45e6-8d83-ad741cc55309' as uniqueidentifier),cast('4e108b91-be3c-4cf4-a074-3767b9b8c7dc' as uniqueidentifier),cast('1cc15f8c-3758-47d3-862a-5287ab5d0651' as uniqueidentifier),cast('e1bf6f5a-800a-4fd4-9309-576c1d84ba2f' as uniqueidentifier),cast('a436b8a9-4b3a-4bf9-bbdd-839571e03915' as uniqueidentifier),cast('b0d6aead-e72f-4fd5-b2cd-e575454d3a4c' as uniqueidentifier),cast('79ddb55a-1587-4928-a312-58da0c091459' as uniqueidentifier),cast('618de87e-2d97-4c0a-b6c1-acd072c305e2' as uniqueidentifier)))
)

也就是说All是包括条件和不在条件之内的任何值,而Any是严格在条件之内的值,但其实我们想要的是Inner Join的方式,相当于是懒加载方式,那么需要加上Include,也就是

IQueryable<WMS_OrgUser> test5 = _db.wmsOrgUser.Include("User").Where(p => ids.Contains(p.OrgId));
SELECT 
1 AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[OrgId] AS [OrgId], 
[Extent1].[UserId] AS [UserId], 
[Extent1].[CreateUser] AS [CreateUser], 
[Extent1].[CreateTime] AS [CreateTime], 
[Extent1].[ModifyUser] AS [ModifyUser], 
[Extent1].[ModifyTime] AS [ModifyTime], 
[Extent1].[RowVersion] AS [RowVersion], 
[Extent2].[Id] AS [Id1], 
[Extent2].[UserName] AS [UserName], 
[Extent2].[NickName] AS [NickName], 
[Extent2].[UserPwd] AS [UserPwd], 
[Extent2].[Sex] AS [Sex], 
[Extent2].[Phone] AS [Phone], 
[Extent2].[Email] AS [Email], 
[Extent2].[QQ] AS [QQ], 
[Extent2].[Address] AS [Address], 
[Extent2].[Remark] AS [Remark], 
[Extent2].[Disable] AS [Disable], 
[Extent2].[CreateUser] AS [CreateUser1], 
[Extent2].[CreateTime] AS [CreateTime1], 
[Extent2].[ModifyUser] AS [ModifyUser1], 
[Extent2].[ModifyTime] AS [ModifyTime1], 
[Extent2].[RowVersion] AS [RowVersion1]
FROM  [dbo].[WMS_OrgUser] AS [Extent1]
INNER JOIN [dbo].[WMS_User] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[Id]
WHERE [Extent1].[OrgId] IN (cast('4e108b91-be3c-4cf4-a074-3767b9b8c7dc' as uniqueidentifier),cast('1cc15f8c-3758-47d3-862a-5287ab5d0651' as uniqueidentifier),cast('e1bf6f5a-800a-4fd4-9309-576c1d84ba2f' as uniqueidentifier),cast('a436b8a9-4b3a-4bf9-bbdd-839571e03915' as uniqueidentifier),cast('b0d6aead-e72f-4fd5-b2cd-e575454d3a4c' as uniqueidentifier)
)

  

条件关联查询,并实现分页
var list = dal.FindByPage(start, pageSize, u => u.OrderByDescending(c => c.CreateTime), u => u.UserOrgIds.All(o => ids.Contains(o.OrgId)), out total);//防止转json时候嵌套异常var result = from f in listselect new{Id = f.Id,UserName = f.UserName,Address = f.Address,Email = f.Email,Sex = f.Sex,CreateUser = f.CreateUser,CreateTime = f.CreateTime,NickName = f.NickName,Phone = f.Phone,QQ = f.QQ,Remark = f.Remark,UserPwd = f.UserPwd};return result;

 

 public virtual IEnumerable<T> FindByPage(int startIndex, int pageSize, Func<IQueryable<T>, IOrderedQueryable<T>> order, Expression<Func<T, bool>> filters, out int Total){try{IQueryable<T> rs = order(DBSET.Where(filters));Total = rs.Count();if (startIndex < 0 || pageSize < 1){return null;// rs.ToList();
                }else{return rs.Skip(startIndex * pageSize).Take(pageSize).ToList();}}catch (Exception e){Total = 0;log.Error("FindByPage:" + order.ToString() + " " + filters.ToString() + " " + e.Message);return null;}}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring5:@Autowired注解、@Resource注解和@Service注解

From: https://www.cnblogs.com/szlbm/p/5512931.html 什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物&#xff0c;这么做有两个缺点&#xff1a; 1、如果所有的内容都配置在.xml文件中&#xff0c;那么.xml文件将会十分庞大&#xff1b;如…

CCNA实验(8) -- PPP HDLC

HDLC帧格式与以太帧格式有很大差别&#xff0c;HDLC帧没有源MAC和目的MAC地址。HDLC不能提供验证&#xff0c;缺少对链路保护。Cisco设备与Cisco设备连接&#xff0c;可用HDLC封装。Cisco设备与非Cisco设备连接&#xff0c;应使用PPP协议。PPP经过4个过程在点到点链路上建立连接…

不使用中间变量交换2个数据

2019独角兽企业重金招聘Python工程师标准>>> 第一种方法&#xff1a; <!-- lang: cpp -->aab;ba-b;aa-b;可能产生越界和溢出。 第二种方法&#xff1a; <!-- lang: cpp -->aa^b;ba^b;aa^b;这种方法只适用整形数。 写成宏的形式 <!-- lang: cpp -->…

slf4j的简单用法以及与log4j的区别

From: https://www.cnblogs.com/qlqwjy/p/9275415.html 之前在项目中用的日志记录器都是log4j的日志记录器&#xff0c;可是到了新公司发现都是slf4j&#xff0c;于是想着研究一下slf4j的用法。 注意:每次引入Logger的时候注意引入的jar包&#xff0c;因为有Logger的包太多了。…

JdbcType类型和Java类型的对应关系

From: https://www.cnblogs.com/tongxuping/p/7134113.html 在Oracle中有些字段不是必填时在用户使用的时候会出现数据null的情况。这个时候在Oracle中是无法进行插入的。 1 JDBC Type Java Type 2 CHAR String 3 VARCHAR String 4 L…

MyBatis Generator配置文件翻译

From: https://www.cnblogs.com/GaiDynasty/p/4088531.html <classPathEntry> 驱动文件指定配置项 <classPathEntry location"/Program Files/IBM/SQLLIB/java/db2java.zip" /> <columnOverride> 将数据库中的字段重命名为实体类的属性 colu…

SpringBoot系列十:SpringBoot整合Redis

From: https://www.cnblogs.com/leeSmall/p/8728231.html 声明&#xff1a;本文来源于MLDN培训视频的课堂笔记&#xff0c;写在这里只是为了方便查阅。 1、概念&#xff1a;SpringBoot 整合 Redis 2、背景 Redis 的数据库的整合在 java 里面提供的官方工具包&#xff1a;j…

海贼王革命家—龙—实力到底如何?

龙——整个海贼王世界中最神秘的人物&#xff0c;令世界政府最担心的存在&#xff0c;是所有迷最为期待的实力展现&#xff0c;他的身上好像有着无数的秘密等着尾田为我们揭晓。 路飞的父亲——未来的海贼王、卡普的儿子——海军英雄、革民军首领——唯一可以跟世界政府抗衡的组…

MyBatis 实践

From&#xff1a; https://www.cnblogs.com/luyiba/p/6303717.html MyBatis简介 MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架. MyBatis是对JDBC的封装,使开发人员只需关注SQL本身,而不需花费过多的精力去处理如注册驱动、设置参数、创建Connectio…

皮克斯背后新技术

2019独角兽企业重金招聘Python工程师标准>>> 皮克斯每创作一部动画作品总会给观众带来或多或少的惊喜&#xff0c;而很多影视动画从业人员也习惯于关注他们的每一部作品的制作&#xff0c;因为新技术往往就在这些制作过程中诞生&#xff0c;如今皮克斯动画已经成为C…

数据结构:二叉查找树(C语言实现)

数据结构&#xff1a;二叉查找树 二叉查找树 基础知识 关于二叉树的基础知识&#xff0c;请看我的一篇博客:二叉树的链式存储 二叉查找树的特征 二叉查找树或者是一棵空树&#xff0c;或者是具有下列性质的二叉树&#xff1a;  1.若其左子树不空&#xff0c;则左子树上所有结…

Effective Java 电子书 apk版本下载

下载安装包以后&#xff0c;安装即可阅读该书了&#xff0c;并且实时展示每章节代码哦&#xff0c;并且可以运行哦&#xff0c;赶快下载体验吧. Effective Java中文第二版下载地址&#xff1a;下载 应用截图&#xff1a; 转载于:https://www.cnblogs.com/spring87/p/6090010.ht…

给你的Mr.Right画张择偶地图像

爱一个人就算做不到爱他的全部&#xff0c;至少也应该尊重他的真实&#xff0c;而不是苛求他变成你想要的样子。 娶妻当娶郭芙蓉&#xff0c;经典语录。我是郭芙蓉&#xff0c;我不会武功&#xff0c;我来自江湖&#xff0c;我与众不同。再苦再累&#xff0c;就当自己是二百五&…

java实现HTTP请求的三种方式

From: https://www.cnblogs.com/hhhshct/p/8523697.html 目前JAVA实现HTTP请求的方法用的最多的有两种&#xff1a;一种是通过HTTPClient这种第三方的开源框架去实现。HTTPClient对HTTP的封装性比较不错&#xff0c;通过它基本上能够满足我们大部分的需求&#xff0c;HttpClien…

SpringBoot时间戳与MySql数据库记录相差14小时排错

From: http://www.cnblogs.com/jason1990/archive/2018/11/28/10032181.html 项目中遇到存储的时间戳与真实时间相差14小时的现象,以下为解决步骤. 问题 CREATE TABLE incident (id int(11) NOT NULL AUTO_INCREMENT,created_time timestamp NOT NULL DEFAULT CURRENT_TIMES…

mysql重置root密码方法

2019独角兽企业重金招聘Python工程师标准>>> 1. 先关闭mysqld 2. 运行&#xff1a; mysqld_safe --skip-grant-tables 3. 另开一个窗口&#xff0c;用 mysql -uroot 登录mysql&#xff0c;执行 UPDATE mysql.user SET PasswordPASSWORD(你的密码) WHERE User…

插入排序之C++实现

描述 插入排序是一种简单直观的排序算法。它的基本思想是将一个待排序的数据序列分为已排序和未排序两部分&#xff0c;每次从未排序序列中取出一个元素&#xff0c;然后将它插入到已排序序列的适当位置&#xff0c;直到所有元素都插入完毕&#xff0c;即完成排序。 实现思路…

Spring在Java Filter注入Bean为Null的问题解决

From: https://www.cnblogs.com/EasonJim/p/7666009.html 在Spring的自动注入中普通的POJO类都可以使用Autowired进行自动注入&#xff0c;但是除了两类&#xff1a;Filter和Servlet无法使用自动注入属性。&#xff08;因为这两个归Web容器管理&#xff09;可以用init&#xf…

Mybatis:resultMap的使用总结

From: https://www.cnblogs.com/kenhome/p/7764398.html Mybatis的介绍以及使用&#xff1a;http://www.mybatis.org/mybatis-3/zh/index.html resultMap是Mybatis最强大的元素&#xff0c;它可以将查询到的复杂数据&#xff08;比如查询到几个表中数据&#xff09;映射到一个…

MyBatis总结六:resultMap详解(包含多表查询)

From: https://www.cnblogs.com/Alex-zqzy/p/9296039.html 简介&#xff1a;   MyBatis的每一个查询映射的返回类型都是ResultMap&#xff0c;只是当我们提供的返回类型属性是resultType的时候&#xff0c;MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性&a…