那天有个小孩跟我说LINQ(二)转载
1 LINQ TO Objects续(代码下载)
新建项目 linq_Ch2控制台程序,新建一个Entity文件夹
1.1 学生成绩查询(练习Join)
有三张表如下:学生表,班级表,成绩表。接下来我们按照这个在Entity文件夹建立3个实体类,类名跟表名一样。
|
|
public class StudentInfo |
public class Classroom
{
/// <summary>
/// 班级Id
/// </summary>
public int ClassId { get; set; } /// <summary>
/// 班级名称
/// </summary>
public string ClassName { get; set; }
}
public class Score
{
/// <summary>
/// 分数Id
/// </summary>
public int ScoreId { get; set; } /// <summary>
/// 学科名称
/// </summary>
public string ItemName { get; set; } /// <summary>
/// 学生ID
/// </summary>
public int StuId { get; set; } /// <summary>
/// 学生
/// </summary>
public Student Students { get; set; } /// <summary>
/// 分数
/// </summary>
public double Scores { get; set; }
}
如上,3个实体类创建好了
①查询出 学生名 学科 分数 3列信息
首先我们初始化一点数据,在void main方法中写
List<Student> students = new List<Student> {
new Student{StuId=,StuName="钱一",ClassId=},
new Student{StuId=,StuName="赵二",ClassId=},
new Student{StuId=,StuName="张三",ClassId=},
new Student{StuId=,StuName="李四",ClassId=},
new Student{StuId=,StuName="王五",ClassId=},
new Student{StuId=,StuName="陈六",ClassId=},
new Student{StuId=,StuName="田七",ClassId=}
};
List<Score> scores = new List<Score> {
new Score{ScoreId=,ItemName="语文",StuId=,Scores=},
new Score{ScoreId=,ItemName="语文",StuId=,Scores=},
new Score{ScoreId=,ItemName="语文",StuId=,Scores=},
new Score{ScoreId=,ItemName="数学",StuId=,Scores=},
new Score{ScoreId=,ItemName="数学",StuId=,Scores=},
new Score{ScoreId=,ItemName="数学",StuId=,Scores=},
new Score{ScoreId=,ItemName="英语",StuId=,Scores=},
new Score{ScoreId=,ItemName="英语",StuId=,Scores=},
new Score{ScoreId=,ItemName="英语",StuId=,Scores=},
new Score{ScoreId=,ItemName="英语",StuId=,Scores=},
new Score{ScoreId=,ItemName="数学",StuId=,Scores=}
};
List<ClassRoom> classrooms = new List<ClassRoom> {
new ClassRoom{ClassId=,ClassName="高三(1)班"},
new ClassRoom{ClassId=,ClassName="高三(2)班"},
new ClassRoom{ClassId=,ClassName="高三(3)班"}
};
开始查询,用集合.Join(另一个集合,第一个集合的条件列,第二个集合的条件列,怎么处理(一个方法))
//学生名 学科 分数
var query1 = students.Join(
scores, //另一个集合
stu => stu.StuId, //建立关系stu.StuId=sc.StuId
sc => sc.StuId,
(s, sc) => new
{
//选出要的数据
学生姓名 = s.StuName,
学科 = sc.ItemName,
分数 = sc.Scores
}
); Console.WriteLine("学生姓名\t学科\t\t分数"); foreach (var stu in query1)
{
Console.WriteLine(string.Format("{0}\t\t{1}\t\t{2}", stu.学生姓名, stu.学科, stu.分数));
} Console.ReadKey();
效果图

第二种方式:
var query2 = from a in students
join b in scores
on a.StuId equals b.StuId
select new
{
学生姓名 = a.StuName,
学科 = b.ItemName,
分数 = b.Scores
}; Console.WriteLine("方式二");
Console.WriteLine("学生姓名\t学科\t\t分数"); foreach (var stu in query2)
{
Console.WriteLine(string.Format("{0}\t\t{1}\t\t{2}", stu.学生姓名, stu.学科, stu.分数));
} Console.ReadKey();
②算学生的总分,查出 学生名 总分
// 学生名 总分(如果分数表找不到,就算0分)
var query3 = from c in query2
group c by c.学生姓名 into stuInfo
select new
{
学生姓名 = stuInfo.Key,
学生总分 = stuInfo.Sum(x => x.分数)
}; Console.WriteLine("求总分的案例");
Console.WriteLine("学生姓名\t总分"); foreach (var stu in query3)
{
Console.WriteLine(string.Format("{0}\t\t{1}", stu.学生姓名, stu.学生总分));
}
效果图:

③左查询(用join实现),DefaultIfEmpty后面括号中的参数是默认值,以students为主表,scores为副表,主表的信息全显示,副表只显示匹配学生Id相同的。
(如果分数表找不到,就算0分)
Console.WriteLine("左查询方式");
var query5 = from a in students
join b in scores
on a.StuId equals b.StuId
into pGroup
from pItem in pGroup.DefaultIfEmpty(new Score { Scores = , ItemName = "没参考", StuId = a.StuId, ScoreId = })
select new
{
学生姓名 = a.StuName,
学科 = pItem.ItemName,
分数 = pItem.Scores
};
Console.WriteLine("学生姓名\t学科\t\t分数");
foreach (var stu in query5)
{
Console.WriteLine(string.Format("{0}\t\t{1}\t\t{2}", stu.学生姓名, stu.学科, stu.分数));
}
Console.ReadKey();

效果图:

如果是数据库,则等同于SQL语句
select s.StuId,s.StuName,s.ClassID,isnull(sc.ScoreId,0),isnull(sc.itemName,'没参考 '),isnull(sc.stuID,0),isnull(sc.score,0) from dbo.Student s left join dbo.Score sc on s.StuID=sc.stuID
④交叉查询
效果图:

代码:
Console.WriteLine("交叉查询方式");
var query6 = from a in students
from b in scores
select new
{
学生姓名 = a.StuName,
学科 = b.ItemName,
分数 = b.Scores
};
Console.WriteLine("学生姓名\t学科\t\t分数");
foreach (var stu in query6)
{
Console.WriteLine(string.Format("{0}\t\t{1}\t\t{2}", stu.学生姓名, stu.学科, stu.分数));
}
等同于SQL:
select * from Student,Score
1.2 类型转换操作
①将数据源转换为IEnumerable<T>类型,使用AsEnumerable<T>方法

②将数据源转换为IQueryable<T>类型,使用AsQueryable<T>方法,用法同上
③将数据源转换成字典类型
代码如下:
//转换成Dictionary
Dictionary<int, Student> query9 = students.ToDictionary(i => i.StuId);
Console.WriteLine(query9[].StuName);
④使用Enumerable类的Cast方法,该方法将非泛型的IEnumerable类型转换为泛型的IEnumerable<T>,至于转换成何种类型有Cast方法的TResult参数指定。
例如:
ArrayList arrList = new ArrayList();
for (int i = ; i < ; i++)
{
arrList.Add(i.ToString());
} var query10 = from i in arrList.Cast<string>()
where i.IndexOf("") > -
select i; foreach (var item in query10)
{
Console.Write(item+",");
}
Console.WriteLine();
效果图:

⑤使用 OfType<T> 筛选指定类型的元素
代码如下:
//OfType<T>
ArrayList arrList2 = new ArrayList();
arrList2.Add();
arrList2.Add("茗洋");
arrList2.Add("A");
arrList2.Add();
arrList2.Add("dd"); var query11=from item in arrList2.OfType<string>()
select item; foreach (var item in query11)
{
Console.Write(item+",");
}
Console.WriteLine();
效果图:

⑥将数据源转换为List<T>类型,使用ToList<T>()方法,用法同IQueryable<T>
⑦将数据源转换为数组类型,使用ToArray()方法,用法同IQueryable<T>
⑧转换为一对多的字典Lookup<TKey,TSource>,与Dictionary区别就是 相同key会对应多个值
下面我们 把班级作为key列出来,然后列出班级里面的学生
var query12 = from o in students
join c in classrooms
on o.ClassId equals c.ClassId
select new Student
{
StuId = o.StuId,
StuName = o.StuName,
ClassId = o.ClassId,
Classrooms = new ClassRoom{
ClassId = c.ClassId,
ClassName = c.ClassName
}
}; ILookup<string, Student> query13 = query12.ToLookup(f => f.Classrooms.ClassName); foreach (var item in query13)
{
Console.WriteLine(item.Key + "的学生如下");
foreach (var stu in item)
{
Console.Write(stu.StuName + ",");
}
Console.WriteLine();
}
效果图如下

1.3 操作集合
. 使用字符串的 EndsWith或者StartsWith过滤,使用CompareTo比较字符串的大小()
例如:找出以“张”开头的学生姓名
//StartWith
var query14 = from o in query2
where o.学生姓名.StartsWith("张")
select o; foreach (var item in query14)
{
Console.Write(item.学生姓名+",");
} Console.WriteLine();
效果图:

其中query2可以是 很多,例如List<T>,string[],IQueryable<T>等
. 操作泛型作排序列表SortList<TKey,TValue>
SortList<TKey,TValue>表示按照键进行排序的键/值对的集合,键/值对是KeyValuePair<TKey,TValue>
//SortList
SortedList<int, Student> users = new SortedList<int, Student>
{
{2,new Student{StuId=2,StuName="钱一",ClassId=1}},
{12,new Student{StuId=12,StuName="赵二",ClassId=1}},
{1,new Student{StuId=1,StuName="张三",ClassId=2}},
}; Console.WriteLine("未按学生姓名排序前的结果如下:"); foreach (var item in users)
{
Console.Write(" 键" + item.Key + ":" + item.Value.StuName);
} var query15 = from s in users
orderby s.Value.StuName descending
select s; Console.WriteLine(); Console.WriteLine("按学生姓名排序后的结果如下:"); foreach (var item in query15)
{
Console.Write(" 键" + item.Key + ":" + item.Value.StuName);
} Console.ReadKey();
效果图

. 操作泛型双向链表LinkedList<T>
泛型双向列表LinkedList<T>表示由T指定类型的双向链表,它通过当前元素可以直接访问该元素的前一个或者后一个元素(如果不存在返回空),元素为LinkedListNode<T>类型

效果图:

代码:
Console.WriteLine(); //LinkedList
LinkedList<int> ints2 = new LinkedList<int>();
ints2.AddFirst(); for (int i = ; i < ; i++)
{
ints2.AddAfter(ints2.Find(i - ), i);
} //使用Linq过滤,排序泛型双向链表
var query16 = from item in ints2
where item > && item <
orderby item descending
select item;
//显示结果
foreach (var item in query16)
{
Console.Write(item.ToString() + ",");
}
另一种方式:
Console.WriteLine();
var query17 = ints2.Where(x => x > && x < ).OrderByDescending(x => x);
//显示结果
foreach (var item in query17)
{
Console.Write(item.ToString() + ",");
}
. 操作泛型队列Queue<T>
先进先出的线性表,使用Enqueue方法进行元素入队(添加)操作,使用Dequeue方法进行元素出队(删除)操作;使用Clear方法进行清空队列 操作。Queue类没有实现IEnumerable<T>接口或IEnumerable接口,所以不能使用LINQ直接操作Queue类型的 对象,可以使用Queue对象的Cast方法先把它转换为IEnumerable<T>类型,然后在使用LINQ对齐操作
Console.WriteLine();
Queue<Student> queues = new Queue<Student>();
queues.Enqueue(new Student { StuId=,StuName="大一",ClassId=});
queues.Enqueue(new Student { StuId = , StuName = "大二", ClassId = });
queues.Enqueue(new Student { StuId = , StuName = "大三", ClassId = });
queues.Enqueue(new Student { StuId = , StuName = "大四", ClassId = });
var query18 = queues.OrderByDescending(x=>x.StuId); //显示结果
foreach (var item in query18)
{
Console.Write(item.StuName + ",");
}
效果图:
如果是Queue先转换成IEnumerable<T>,在LINQ操作
. 操作泛型堆栈Stack<T>
后进先 出的线性表,使用Push方法进行元素入栈(添加)操作,使用Dequeue方法进行元素出栈(删除)操作;使用Clear方法进行清空堆栈操作。 Stack类没有实现IEnumerable<T>接口或IEnumerable接口,所以不能使用LINQ直接操作Queue类型的对象, 可以使用Stack对象的Cast方法先把它转换为IEnumerable<T>类型,然后在使用LINQ对齐操作
效果图:
代码:
Console.WriteLine();
Stack<Student> stacks = new Stack<Student>();
stacks.Push(new Student { StuId = , StuName = "大一", ClassId = });
stacks.Push(new Student { StuId = , StuName = "大二", ClassId = });
stacks.Push(new Student { StuId = , StuName = "大三", ClassId = });
stacks.Push(new Student { StuId = , StuName = "大四", ClassId = });
var query19 = from s in stacks
where s.ClassId != || s.StuId!=
select s; //显示结果
foreach (var item in query19)
{
Console.Write(item.StuName + ",");
}
. 操作泛型哈希集HashSet<T>
后泛型哈希集HashSet<T>是由T指定类型的基于集合的模型,泛型哈希集可以提供高性能的如并集,交集,补集等集合运算。泛型哈希集中的元素不能重复。泛型哈希集提供许多集合操作,如并集,交集,补集等。
代码:
/*HashSet*/
Console.WriteLine();
HashSet<Student> hashsets = new HashSet<Student> {
new Student{StuId=,StuName="钱一",ClassId=},
new Student{StuId=,StuName="赵二",ClassId=},
new Student{StuId=,StuName="张三",ClassId=},
new Student{StuId=,StuName="李四",ClassId=},
new Student{StuId=,StuName="王五",ClassId=},
new Student{StuId=,StuName="陈六",ClassId=},
new Student{StuId=,StuName="田七",ClassId=}
}; hashsets.Add(new Student { StuId = , StuName = "大一", ClassId = });
//先按班级升序排序,再按姓名降序
var query20 = from s in hashsets
orderby s.ClassId ascending, s.StuName descending
select s; //显示结果
foreach (var item in query20)
{
Console.Write(item.StuName + ",");
}
效果图:
. 操作泛型字典Dictionary<TKey,TValue>
键不能重复,值可重复,键不会自动排序
代码:query9是一个Dictionary类型的
Console.WriteLine();
var query21 = from o in query9
where o.Value.StuName.CompareTo("张") > //学生姓名大于“张”
orderby o.Key
select o; foreach (var item in query21)
{
Console.WriteLine(item.Key + ":"+item.Value.StuName);
}
效果图:

. 操作泛型排序字典SortedDictionary<TKey,TValue>
与Dictionary<TKey,TValue>的区别:泛型排序字典对添加的元素自动按键进行排序,代码例如:SortDictionary<int,Student> c=new SortDictionary<int,Student>{…….}
. 操作泛型通用集合Collection<T>,跟List<T>一样用就行了
. 操作泛型绑定列表 BindingList<T>
泛型绑定列表BindingList<T>能够提供支持数据绑定的泛型集合,他提供了IBindingList接口的具体泛型实现,可以用作创建双向数据绑定机制的积累,还可以通过AddNew方法支持创建实例
跟List<T>一样用就行了
关于还剩一点linq to objects明天写,顺便带点Linq to SQL
那天有个小孩跟我说LINQ(二)转载的更多相关文章
- 那天有个小孩跟我说LINQ(五)转载
2 LINQ TO SQL(代码下载) 我们以一个简单的销售的业务数据库为例子 表结构很简单:Users(购买者(用户)表),Products(产品信息表),Sales(销 ...
- 那天有个小孩跟我说LINQ(七)转载
1 LINQ TO XML(代码下载) 准备:新建项目 linq_Ch7控制台程序,新建一个XML文件夹,我们就轻松地学习一下吧 XDocument ...
- 那天有个小孩跟我说LINQ(六)转载
2 LINQ TO SQL完结(代码下载) 我们还是接着上次那个简单的销售的业务数据库为例子,打开上次那个例子linq_Ch5 2.1 当数据库中的表建立了主外键 ①根据主键获取子表信息 ...
- 那天有个小孩跟我说LINQ(四)转载
1 LINQ TO SQL(代码下载) 我们以一个酒店管理系统的数据库为例子 表结构很简单:GuestInfo(客人信息表),Room(房间表),RoomType(房间类 ...
- 那天有个小孩跟我说LINQ(三)转载
1 LINQ TO Objects续2(代码下载) 新建项目 linq_Ch3控制台程序 1.1 操作字符串 ①查找字符串中包含的大写字母,字符串是由多个char类型组 ...
- 那天有个小孩跟我说LINQ(一) 转载
1 LINQ准备(代码下载) 新建项目 linq_Ch1控制台程序,新建一个Entity文件夹 1.1 对象初始化器 在Entity新建一个类Student,代码如下 using S ...
- 那天有个小孩跟我说LINQ(八)学会Func
文章已经迁移到:http://www.ayjs.net/2013/08/68/ 文章已经迁移到:http://www.ayjs.net/2013/08/68/ 文章已经迁移到:http://www.a ...
- 那天有个小孩教我WCF[一][2/3]
接着上次的继续讲吧 我们开始吧 9.创建数据库 use master go --创建库 if exists(select * from sysdatabases where name='NewsDB' ...
- 那天有个小孩教我WCF[一][1/3]
那天有个小孩教我WCF[一][1/3] 既然是小孩系列,当然要有一点基础才能快速掌握,归纳,总结的一个系列,哈哈 前言: 第一篇嘛,不细讲,步步教你创建一个简单SOA案例,对WCF有个基本的认识,我不 ...
随机推荐
- codeforces 652E Pursuit For Artifacts 边双连通分量
题意:n个点,m条边的无向图,有的边上有标记,每条边只能走一次 给你一个起点,一个终点,询问是否能找到从起点到终点的路径,这条路径至少包含一条含有标记的边 分析:然后边双缩点 下面介绍一下边双的性质 ...
- [Tommas] SQL 中 WITH AS 的用法
WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到: 下面的例子定义了一个 Temp 片段,Te ...
- OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图
读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了 代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退 ...
- Java笔记(十八)……包
概述 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是 包名.类名. 包也是一种封装形式. 访问权限 引用<The Complete Reference&g ...
- wuzhicms发送邮件
//邮件发送 $config = get_cache('sendmail'); $siteconfigs = get_cache('siteconfigs'); $password = decode( ...
- HDU POJ 1015 Jury Compromise(陪审团的人选,DP)
题意: 在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候 ...
- Spring笔记(四)SpingAOP
需要的Jar包(String3.2) com.springsource.net.sf.cglib-2.2.0.jar // 作用于cglib方式的动态代理 com.springsource.org.a ...
- 问题-[Delphi7]程序在WIN7电脑上的日期错误处理
问题现象:我想大家都遇到过在XP上没有问题的日期格式,到了WIN7之后就不行了. 问题原因:因为在WIN7中增加了新的日期格式,但是老的DELPHI未处理(如果我说错了,希望高人指点). 问题处理: ...
- A Tour of Go The new function
The expression new(T) allocates a zeroed T value and returns a pointer to it. var t *T = new(T) or t ...
- Zabbix lld发现磁盘监控
一.软件版本 操作系统:CentOS-6.5-x86_64 zabbix版本:3.0.3 二.脚本编写: 1.python版本: #!/usr/bin/env python import json i ...
