linq之join子句

  前面我们总结Linq查询子句总共有8个,join子句是我们讲解的最后一个子句。join子句也是相对比较复杂的,所以最后来讲。join子句可以处理两个数据源之间的联系,当然这两个数据源之间必须存在相关联的值。

join子句可以实现3中连接关系

1.内部联接:元素的联接关系必须同时满足被连接的两个数据源

2.分组联接:含有into子句的join子句

3.左外部联接

下面我们就详细的分析一下这三种联接方式。

准备数据:

除了前面用到的UserBaseInfo类,我们新增一个roles类:

 1 using System;
 2 using System.Data;
 3 using System.Configuration;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Security;
 7 using System.Web.UI;
 8 using System.Web.UI.HtmlControls;
 9 using System.Web.UI.WebControls;
10 using System.Web.UI.WebControls.WebParts;
11 using System.Xml.Linq;
12 using System.Collections;
13 using System.Collections.Generic;
14 
15 namespace LinqQueryDemo
16 {
17    /// <summary>
18 /// 角色的基本信息
19 /// </summary>
20 public class RoleInfo
21 {
22     private int id;
23     private string roleName;
24 
25     /// <summary>
26     /// 角色的ID值
27     /// </summary>
28     public int ID
29     {
30         get { return id; }
31         set { id = value; }
32     }
33     /// <summary>
34     /// 角色的名称
35     /// </summary>
36     public string RoleName
37     {
38         get { return roleName; }
39         set { roleName = value; }
40     }
41 
42     public RoleInfo(int id, string roleName)
43     {
44         this.id = id;
45         this.roleName = roleName;
46     }
47 }
48 }

内部联接

  内部联接和sqlserver中的inner join类似,联接关系必须同时满足两个被联接的数据源。下面代码中的InnerJoinQuery方法演示了内部联接users和roles数据源的查询方法。

     

 1  private void InnerJoinQuery()
 2         {
 3 
 4             List<UserBaseInfo> users = new List<UserBaseInfo>();
 5             List<RoleInfo> roles = new List<RoleInfo>();
 6 
 7 
 8             for (int i = 1; i < 10; i++)
 9             {
10                 users.Add(new UserBaseInfo(i, "users0" + i.ToString(), "user0" + i.ToString() + "@web.com", i * 2));
11                 roles.Add(new RoleInfo(i, "RoleName0" + i.ToString()));
12             }
13 
14             //查询ID值小于9,且角色包含roles中的用户
15             var result = from u in users
16                          join r in roles on u.RoleId equals r.ID
17 
18                          where u.ID < 9
19                          select u;
20 
21             foreach (var u in result)
22             {
23 
24                     Response.Write(u.UserName + "</br>");
25  
26             }
27         }

查询结果:

分组联接

含有into子句的join子句被分组连接。分组联接产生分层数据结构。它将第一个集合中的每个元素与第二个集合中的元素进行匹配,在查询结果中,第一个集合中的元素都会出现,第二个集合中的元素如果匹配成功,则使用被找到的元素否则为空。

下面的groupjoinquery函数演示分组联接。

 1 private void GroupJoinQuery()
 2         {
 3 
 4             List<UserBaseInfo> users = new List<UserBaseInfo>();
 5             List<RoleInfo> roles = new List<RoleInfo>();
 6 
 7 
 8             for (int i = 1; i < 10; i++)
 9             {
10                 users.Add(new UserBaseInfo(i, "users0" + i.ToString(), "user0" + i.ToString() + "@web.com", i * 2));
11                 roles.Add(new RoleInfo(i, "RoleName0" + i.ToString()));
12             }
13 
14             //查询ID值小于9,且角色包含roles中的用户
15             var result = from u in users
16                 join r in roles on u.RoleId equals r.ID into g
17 
18                 where u.ID < 9
19                 select new
20                 {
21                     ID = u.ID,
22                     UserName = u.UserName,
23                     Email = u.Email,
24                     RoleId = u.RoleId,
25                     Roles = g.ToList()
26                 };
27  foreach (var u in result)
28             {
29 
30                 Response.Write(u.UserName +","+(u.Roles.Count>0?u.Roles[0].RoleName:string.Empty)+ "</br>");
31  
32             }
33         }

查询结果:

左外部联接

左外部联接跟sqlserver中的left join相似。他返回第一个集合中的所有元素,第二个集合中与第一个集合相关的元素显示。如果第二个集合中没有找到相关的元素,就用DefaultEmpty方法来指定默认值。

 1  private void LeftOuterJoinQuery()
 2         {
 3 
 4             List<UserBaseInfo> users = new List<UserBaseInfo>();
 5             List<RoleInfo> roles = new List<RoleInfo>();
 6 
 7 
 8             for (int i = 1; i < 10; i++)
 9             {
10                 users.Add(new UserBaseInfo(i, "users0" + i.ToString(), "user0" + i.ToString() + "@web.com", i * 2));
11                 roles.Add(new RoleInfo(i, "RoleName0" + i.ToString()));
12             }
13 
14             //查询ID值小于9,且角色包含roles中的用户
15             var result = from u in users
16                          where u.ID < 9
17                 join r in roles on u.RoleId equals r.ID into gr
18                 from ur in gr.DefaultIfEmpty()
19                 select new
20                 {
21                     ID = u.ID,
22                     UserName = u.UserName,
23                     Email = u.Email,
24                     RoleId = u.RoleId,
25                     Roles = gr.ToList()
26                 };
27  foreach (var u in result)
28             {
29 
30                 Response.Write(u.UserName +","+(u.Roles.Count>0?u.Roles[0].RoleName:string.Empty)+ "</br>");
31  
32             }
33         }

运行结果:

原文地址:https://www.cnblogs.com/yplong/p/5413679.html