本篇讲解LINQ查询的三种形式:
【1.查询结果返回集合元素】
在LINQ查询中,select子句和from子句都是必备子句。LINQ查询表达式必须以select或group子句结束。select子句指定在执行查询时产生结果的数据集中元素的类型,它的格式如下:
select element
其中,select是关键字,element参数则指定查询结果中元素的类型及初始化方式。
在进一步介绍select子句之前,首先简单介绍一下本章例子中要用到的Student类,该类表示一个学生信息。它包括一个构造函数,并重写ToString()方法产生Student的字符串形式。
Student(学生信息)类的具体实现如下:
/// <summary> /// 学生类,用来表示学生的姓名、性别、学习成绩等 /// </summary> class Student { private string _Name; // 学生姓名 private string _Gender; // 学生性别 private uint _Age; // 学生年龄 private List<LessonScore> _Scores; // 学生成绩单,一个LessonScore类列表 /// <summary> /// 构造函数 /// </summary> /// <param name="name">姓名</param> /// <param name="gender">性别</param> /// <param name="age">年龄</param> /// <param name="scores">成绩单</param> public Student(string name, string gender, uint age, List<LessonScore> scores) { this._Name = name; this._Gender = gender; this._Age = age; this._Scores = scores; } /// <summary> /// 构造函数 /// </summary> /// <param name="name">姓名</param> /// <param name="gender">性别</param> /// <param name="age">年龄</param> public Student(string name, string gender, uint age) { this._Name = name; this._Gender = gender; this._Age = age; this._Scores = null; // 设置默认成绩单为null } /// <summary> /// 学生成绩单,一个LessonScore类列表 /// </summary> internal List<LessonScore> Scores { get { return _Scores; } set { _Scores = value; } } /// <summary> /// 学生年龄 /// </summary> public uint Age { get { return _Age; } set { _Age = value; } } /// <summary> /// 学生性别 /// </summary> public string Gender { get { return _Gender; } set { _Gender = value; } } /// <summary> /// 学生姓名 /// </summary> public string Name { get { return _Name; } set { _Name = value; } } /// <summary> /// 重写ToString(),获取格式化后学生的信息 /// </summary> /// <returns>生成表示学生信息的字符串</returns> public override string ToString() { string result; result = string.Format("{0}-{1}-{2}", this._Name, this._Age, this._Gender); return result; } }
Student(学生信息)类具体实现
LessonScore(成绩表)类具体实现如下:
/// <summary> /// 学生成绩类 /// </summary> class LessonScore { private float _Score; // 课程成绩 private string _Lesson; // 课程名称 /// <summary> /// 创建成绩表单 /// </summary> /// <param name="les">课程名</param> /// <param name="scr">分数</param> public LessonScore(string les, float scr) { this._Lesson = les; this._Score = scr; } /// <summary> /// 课程成绩 /// </summary> public float Score { get { return _Score; } set { _Score = value; } } /// <summary> /// 课程名称 /// </summary> public string Lesson { get { return _Lesson; } set { _Lesson = value; } } /// <summary> /// 重写ToString()方法,输出指定格式的成绩信息 /// </summary> /// <returns></returns> public override string ToString() { string result; result = string.Format("{0}==={1}分", this._Lesson, this._Score); return result; } }
LessonScore(成绩表)类具体实现
select子句中如果不指定元素的具体类型,编译器会将查询中元素的类型自动设置为select子句中元素的具体类型。
如果下面的示例代码,在from子句中stuItem根据students元素的类型自动判断为Student类型。select子句中指定stuItem为查询结果,并没有指定类型。
那么自动判断为Student类型,queryResult的类型则为IEnumerable<Student>:
static void Main(string[] args) { // 创建学生数组列表students作为数据源 Student[] students = { ), ), ), ), ) }; var queryResult = (from stuItem in students select stuItem); // 查询queryResult返回数据源students中所有元素 // 打印查询queryResult的所有元素 foreach (Student item in queryResult) { Console.WriteLine(item); }
上面代码输出结果如下,foreach遍历queryResult中的元素,并打印元素的文本表示,调用Student类的ToString()方法来获得文本格式:
【2.查询结果返回自定义属性】
select子句中要选择的目标数据不仅可以为数据源中的元素,还可以是该元素的不同操作结果,包括属性、方法和运算等。
如下面的示例代码:
queryNameResults中将学生的姓名(Name属性)作为查询结果,其是IEnumerable<string>类型;
queryNameLengthResults则是学生的姓名(Name属性)的字符数作为查询结果,其是IEn<int>类型。
static void Main(string[] args) { // 创建学生数组列表students作为数据源 Student[] students = { ), ), ), ), ) }; // 查询queryNameResults返回数据源students中所有学生的姓名 var queryNameResults = (from stuItem in students select stuItem.Name); // 打印查询queryNameResults的元素 foreach (string item in queryNameResults) { Console.Write("{0} ", item); } Console.WriteLine(); // 查询queryNameLengthResults返回数据源students中所有学生姓名的字符长度 var queryNameLengthResults = (from stuItem in students select stuItem.Name.Length); // 打印查询queryNameLengthResults的元素 foreach (int item in queryNameLengthResults) { Console.Write("{0},", item); Console.WriteLine(); }
上面代码的运行结果如下,其中,第一行是queryNameResults查询结果,即学生姓名的集合中的元素。第二行是queryNameLengthResults的查询结果,即所有学生姓名字符数的集合元素:
【3.查询结果返回匿名类型】
在某些特殊的场合下,往往查询结果只是临时使用一下,而且查询结果的数据包括很多字段,并非简单的一个属性、方法返回值等。在LINQ中可以在select子句中使用匿名类型来解决这类问题。
如下面的示例代码,查询表达式queryResult的select子句通过匿名类型定义关键字让编译器自动判断查询中元素类型:
static void Main(string[] args) { // 创建学生数组列表students作为数据源 Student[] students = { ), ), ), ), ) }; // 查询queryResult返回数据源students中学生的姓名、年龄、姓名长度 // 以匿名类型方式返回 var queryResult = (from item in students select new { item.Name, item.Age, NameLength = item.Name.Length }); // 打印查询queryResult中的元素 foreach (var item in queryResult) { Console.WriteLine(item); } }
运行结果如下,输出结果是匿名类的ToString()方法产生文本:
技巧:通常情况下,不需要为select子句中的元素指定具体数据类型。另外,如果查询结果中的元素只是在本函数内临时使用,尽量使用匿名类型,这样可以减少很多不必要的类定义。
内容参考:
《精通C#5.0与.NET 4.5高级编程——LINQ、WCF、WPF和WF》
【来自 孤影'Blog:http://www.cnblogs.com/LonelyShadow,码字不容易,转载请注明出处。】