EF5.x Code First一对多关联条件查询Contains、Any和All使用示例

12 篇文章 0 订阅
3 篇文章 0 订阅

背景
通过多个部门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   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 < 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;              }          } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值