背景

通过多个部门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 list
select 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 < || pageSize < )
{
return null;// rs.ToList();
}
else
{
return rs.Skip(startIndex * pageSize).Take(pageSize).ToList();
}
}
catch (Exception e)
{
Total = ;
log.Error("FindByPage:" + order.ToString() + " " + filters.ToString() + " " + e.Message);
return null;
}
}

EF5.x Code First 一对多关联条件查询,Contains,Any,All的更多相关文章

  1. mybatis一对多根据条件查询的查条数

    一对多写了mapper映射之后 根据条件查条数 可以根据主表的唯一id进行分组 在拿到它的count select count(0) over(aa.id),,id,name,age from tab ...

  2. Mybatis学习——一对多关联表查询

    1.实体类 public class Student { private int id; private String name; } public class Classes { private i ...

  3. ThinkPHP5——模型关联(一对多关联)

    关联定义 一对多关联的情况也比较常见,使用hasMany方法定义,参数包括: hasMany('关联模型名','外键名','主键名',['模型别名定义']); 例如租客表和宿舍表,一个宿舍有多个租客, ...

  4. EF Code First 一对多、多对多关联,如何加载子集合?

    应用场景 先简单描述一下标题的意思:使用 EF Code First 映射配置 Entity 之间的关系,可能是一对多关系,也可能是多对多关系,那如何加载 Entity 下关联的 ICollectio ...

  5. [转]NHibernate之旅(10):探索父子(一对多)关联查询

    本节内容 关联查询引入 一对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 关联查询引入 在NHibernate中提供了三种查询方式给我们选择:NH ...

  6. MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查

    MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查 本文的目的:   1.MVC3项目简单配置EF code first生成并初始化数据 ...

  7. mybatis collection 一对多关联查询,单边分页的问题总结!

    若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...

  8. MyBatis关联查询、多条件查询

    MyBatis关联查询.多条件查询 1.一对一查询 任务需求; 根据班级的信息查询出教师的相关信息 1.数据库表的设计 班级表: 教师表: 2.实体类的设计 班级表: public class Cla ...

  9. Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)

    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...

随机推荐

  1. 【转载,整理】Linux性能监控

    一. 比较全的linux性能检测网站 1. 很好的网站,原文:http://os.51cto.com/art/201402/430050.htm 监测 cpu.内存.网络.IO等命令及工具   2.  ...

  2. Android Developers:支持不同的屏幕密度

    这节课程向你展示如何通过提供不同的资源和使用与分辨率无关的测量单位,支持不同屏幕密度. 使用密度无关的像素 —————————————————————————————————————————————— ...

  3. [转]PostgreSQL教程(十六):系统视图详解

    这篇文章主要介绍了PostgreSQL教程(十六):系统视图详解,本文讲解了pg_tables.pg_indexes.pg_views.pg_user.pg_roles.pg_rules.pg_set ...

  4. 【OfficeWebViewer】在线预览Word,Excel~

    今天有个需求, 直接支持web端预览word,excel等文件, 查了一下很多写的比较麻烦, 这里找到一种简单的方式: http://view.officeapps.live.com/op/view. ...

  5. LVL类及接口使用介绍(License Verification Library )

    原文:http://android.eoe.cn/topic/android_sdk LVL Classes and Interfaces-LVL类和接口 Table 1 lists all of t ...

  6. Android TextView 支持的HTML标签

    * <a href="...">    * <b>    * <big>    * <blockquote>    * <br ...

  7. ios block一定会犯的几个错误

    贴几段斯坦福大学关于gcd的代码,这段代码逐步演示了如何修正错误,其中用到的既是串行队列   1.这个是原始代码 - (void)viewWillAppear:(BOOL)animated { NSD ...

  8. android应用开发-从设计到实现 3-3 Sketch静态原型设计

    Sketch静态原型设计 对于静态原型的设计,我们使用Sketch. 启动Sketch后,我们将看到相似例如以下的界面, 工具栏 它的顶部是工具栏, 能够通过菜单条View -> Customi ...

  9. yum 卸载 error: %preun(tengine-2.1.0-1.el6.x86_64) scriptlet failed, exit status 6

    error: %preun(tengine-2.1.0-1.el6.x86_64) scriptlet failed, exit status 6 Error in PREUN scriptlet i ...

  10. 如何在 Linux 上设置密码策略

    https://linux.cn/article-2518-1.html 用户帐号管理是系统管理员最重要的工作之一.而密码安全是系统安全中最受关注的一块.在本教程中,我将为大家介绍如何在 Linux ...