Linq学习之操作符
2013-11-19 19:21 y-z-f 阅读(510) 评论(0) 编辑 收藏 举报一、环境搭建
下面将逐步搭建我们学习的环境,这个环境不仅仅是这次需要使用,以后的教程一样需要使用这个环境。所以请大家务必按照
搭建这里的环境否则会影响你后面的学习。
-
我们用到的几张表
通知消息表:
用户表: -
在VS中生成表
2.1 新建一个控制台程序(略)
2.2 新建一个Linq To Sql类
2.3 新建数据连接
2.4 添加连接
2.5 映射表
环境到此已经设置完毕,后面我们将开始正式的学习
二、操作符学习
-
投影操作符
简单点说就是更SQL语句中的 AS 操作符一个意思,就是把列名换掉。但是我们这里的投影远比SQL语句中的AS
拥有更强大的地方。
1.1.1 下面是一个简单的投影使用
1 static void Main(string[] args) 2 { 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = from item in dc.Db_SST_Notic 5 select new { NID = item.NoticID, NTitle = item.NoticTitle }; 6 //这里使用 new 将 NoticID 的列名改为 NID,将 NoticTitle 的列名改为 NTitle 7 //最后的result就会 8 foreach (var item in result) 9 { 10 System.Console.WriteLine(" ID = {0}; Title = {1} ", item.NID, item.NTitle); 11 } 12 System.Console.ReadKey(); 13 }
1.1.2 最后遍历result的时候,item中除了集成自Object的基本方法以外,就是投影的属性名如图:
1.1.3 这是最后的结果(数据根本个人情况会不一样)
1.2.1 下面来演示一个较复杂的
1 //新建的一个数据模型 2 class Modal 3 { 4 public int NID { get; set; } 5 public String NTitle { get; set; } 6 } 7 8 static void Main(string[] args) 9 { 10 LinqDataDataContext dc = new LinqDataDataContext(); 11 //将最终结果投影成我们自己数据模型 12 IEnumerable<Modal> result = from item in dc.Db_SST_Notic 13 select new Modal() 14 { 15 NID = item.NoticID, 16 NTitle = item.NoticTitle 17 }; 18 //这里使用 new 将 NoticID 的列名改为 NID,将 NoticTitle 的列名改为 NTitle 19 //最后的result就会 20 foreach (var item in result) 21 { 22 System.Console.WriteLine(" ID = {0}; Title = {1} ", item.NID, item.NTitle); 23 } 24 System.Console.ReadKey(); 25 }
其中我们新建了一个数据模型,然后使用投影,将最终的数据投影成我们新建的数据模型,最终的结果更上面的结果一样。
-
限制操作符
简单说就是SQL语句中的where,就是用来对数据进行筛选。
2.1 下面是一个用来获得重要通知的语法
1 static void Main(string[] args) 2 { 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 //将最终结果投影成我们自己数据模型 5 var result = from item in dc.Db_SST_Notic 6 where item.IsMust.Value 7 select new 8 { 9 NID = item.NoticID, 10 NTitle = item.NoticTitle 11 }; 12 foreach (var item in result) 13 { 14 System.Console.WriteLine(" ID = {0}; Title = {1} ", item.NID, item.NTitle); 15 } 16 System.Console.ReadKey(); 17 }
其中的 where item.IsMust.Value 就是用来将重要的通知从中筛选出来
2.2 下面是最终的结果 -
排序操作符
等同于SQL语句中的orderby
3.1 下面是一个按通知ID逆序,并且按发送时间正序的语法
1 static void Main(string[] args) 2 { 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = from item in dc.Db_SST_Notic 5 where item.IsMust.Value 6 orderby item.NoticID descending,item.SendTime 7 select new 8 { 9 NID = item.NoticID, 10 NTitle = item.NoticTitle 11 }; 12 foreach (var item in result) 13 { 14 System.Console.WriteLine(" ID = {0}; Title = {1} ", item.NID, item.NTitle); 15 } 16 System.Console.ReadKey(); 17 }
通过上面的 orderby item.NoticID descending,item.SendTime 就可以将数据进行排序
3.2 下面是结果 -
联接操作符
等同于SQL语句中的inner join
4.1 下面是一个将通知表与用户表进行关联的语句
1 static void Main(string[] args) 2 { 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = from item in dc.Db_SST_Notic 5 join user in dc.Sys_SST_User on item.SendNoticUserID equals user.UserID 6 where item.IsMust.Value 7 orderby item.NoticID descending, item.SendTime 8 select new 9 { 10 NID = item.NoticID, 11 NTitle = item.NoticTitle, 12 User = user.UserName 13 }; 14 foreach (var item in result) 15 { 16 System.Console.WriteLine(" ID = {0}; Title = {1}; User = {2} ", item.NID, item.NTitle,item.User); 17 } 18 System.Console.ReadKey(); 19 }
其中join 后面跟着的 user in dc.Sys_SST_User 就是获取用户表的集合,后面的 on item.SendNoticUserID equals user.UserID 就是关联
的条件,这样就可以将用于表与通知表进行关联了,然后注意最后的投影,我们多了一个 User = user.UserName 这样我们就可以在最后的结果
中看到发送该通知的用户。
4.2 下面是最后的结果 -
特殊的联接操作符
这个操作符可以用来获取两张存在一对多的关系的数据,比如这里用户可以对应多条通知,假如我们需要显示每个用户发送的通知,以一种
父子的关系来呈现,我们可以用以下的语句来实现。
5.1
1 static void Main(string[] args) 2 { 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 //var result = from item in dc.Db_SST_Notic 5 // join user in dc.Sys_SST_User on item.SendNoticUserID equals user.UserID 6 // where item.IsMust.Value 7 // orderby item.NoticID descending, item.SendTime 8 // select new 9 // { 10 // NID = item.NoticID, 11 // NTitle = item.NoticTitle, 12 // User = user.UserName 13 // }; 14 var result = dc.Sys_SST_User.GroupJoin(dc.Db_SST_Notic, user => user.UserID, notic => notic.SendNoticUserID, (user, notic) => 15 new { UserID = user.UserID, Name = user.UserName, notics = notic.Select(n => n.NoticTitle) }); 16 foreach (var item in result) 17 { 18 System.Console.WriteLine(" UserID = {0} ; Name = {1} ", item.UserID,item.Name); 19 foreach (string subitem in item.notics) 20 { 21 System.Console.WriteLine(" Title = {0} ", subitem); 22 } 23 } 24 System.Console.ReadKey(); 25 }
其中 GroupJoin 的第一个参数是需要联接的表,第二个参数是 Sys_SST_User 的条件字段(用来和第三个参数进行对比),第三个参数是
这里可以看到最终的结果,就是一种从属的关系。
第一个参数表中的条件字段(用来与第二个参数进行对比),最后的参数就是在将两个表中的条件进行对比后的结果,其中user参数表示一个
用户数据,而notic表示的是多个通知,这里我们就可以使用投影来获取我们需要的数据。
5.2 下面是最终的结果(我可截取了存在通知的用户) -
聚合操作符
聚合操作符基本都是SQL语句中的MAX、MIN、COUNT、AVERAGE等
6.1 Aggregate操作符
它的功能就是将上一次的结算结果作为执行函数的第一个参数,将当前处理的数据作为第二个参数,并且把返回的参数作为
下一个执行方法的第一个参数。
6.1.1 下面是一个累加的实现
1 int[] s = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 2 var result = (from item in s 3 select item).Aggregate( 4 (ct, nt) => { return ct + nt; }); 5 System.Console.WriteLine(" NIDADD = {0} ", result);
这里我要说明一下,为什么我们这里是对一个数组的数据进行操作,而不是之前对一个集合,因为集合是不支持单一的循环的
当然你在SQL语句中可能用过游标,而游标的实现方式就是面对行而不是集合。
6.1.2 下面是结果
6.2 Average操作符
它的功能就是求结果的平均值
6.2.1 下面我们举一个求通知ID的平均值
1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.NoticID).Average(); 4 System.Console.WriteLine(" Average is {0}", result);
6.2.2 下面是最终的结果6.3 Count操作符
它的功能就是求结束的数量
6.3.1 下面是输出通知的总数
1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.NoticID).Count(); 4 System.Console.WriteLine(" Count is {0}", result);
6.3.2 下面是最终结果
提示下Count操作符只能返回不超过Int32能够表示的数量范围。如果数据量会超过Int32所能表示的范围,可以使用下面
介绍的操作符。
6.4 LongCount操作符
6.4.1 下面是输出通知的总数1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.NoticID).LongCount(); 4 System.Console.WriteLine(" Count is {0}", result);
6.4.2 最终结果同上
6.5 Max操作符
它的功能就是求结果数据中最大的一条数据
6.5.1 下面是求通知ID中的最大ID1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.NoticID).Max(); 4 System.Console.WriteLine(" Count is {0}", result);
6.5.2 下面是最终结果
6.6 Min操作符
它的功能就是求结果数据中最小的一条数据
6.6.1 下面是输出通知ID中最小的ID1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.NoticID).Min(); 4 System.Console.WriteLine(" Max is {0}", result);
6.6.2 下面是最终结果 -
集合操作符
7.1 Distinct操作符
用于去除结果中重复的值
7.1.1 下面是用来获取已经发送通知的用户ID
用于通知可以由一个用户发送多个,所以直接搜索就会出现重复。
1 LinqDataDataContext dc = new LinqDataDataContext(); 2 var result = (from item in dc.Db_SST_Notic 3 select item.SendNoticUserID).Distinct(); 4 foreach (var item in result) 5 { 6 System.Console.WriteLine(" UserID = {0} ", item.Value); 7 } 8 System.Console.ReadKey();
7.1.2 下面最后的结果
7.2 Union操作符
用于将两个结果集合并但是不会显示重复的数据
7.2.1 下面我们新建两个数组然后进行合并
1 int[] i1 = new int[] {1,2,3 }; 2 int[] i2 = new int[] { 1, 2, 3, 4, 5, 6, 7 }; 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = i1.Union(i2); 5 foreach (var item in result) 6 { 7 System.Console.WriteLine(" UserID = {0} ", item); 8 } 9 System.Console.ReadKey();
7.2.2 下面是最终的结果
7.3 Intersect操作符
用于返回两个集合中都存在的数据
7.3.1 下面我们继续使用上面的数据然后改变为交集1 int[] i1 = new int[] {1,2,3 }; 2 int[] i2 = new int[] { 1, 2, 3, 4, 5, 6, 7 }; 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = i1.Intersect(i2); 5 foreach (var item in result) 6 { 7 System.Console.WriteLine(" UserID = {0} ", item); 8 } 9 System.Console.ReadKey();
7.3.2 下面是最终的结果
7.4 Except操作符
它的功能与Intersect操作符刚好相反,它是将在两个集合中没有同时存在的值返回
7.4.1 下面我们继续使用上面的数据然后改变方式为差集1 int[] i1 = new int[] {1,2,3 }; 2 int[] i2 = new int[] { 1, 2, 3, 4, 5, 6, 7 }; 3 LinqDataDataContext dc = new LinqDataDataContext(); 4 var result = i2.Except(i1); 5 foreach (var item in result) 6 { 7 System.Console.WriteLine(" UserID = {0} ", item); 8 } 9 System.Console.ReadKey();
7.4.2 下面是最终结果