- 浏览: 138642 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
gezi2213:
...
HttpClient及有关jar包详解 -
sailor119:
学习一下!
〖ExtJS〗之ToolBar
LINQ标准查询操作符详解
标准查询操作符就是可以查询任何.NET数组或者集合的API,这个API由System.Query.Sequence静态类中声明的方法组成。标准查询操作符遵守.NET 2.0通用语言规范并且可以用于任何支持范型的.NET编程语言。标准查询操作符可以操作所有实现了IEnumerable<T>接口的对象。
我们将采用一个假设使用场景为学校的示例来讲解标准查询操作符的使用。我们假设有这样几个类:
1: /// <summary>
2: /// The data class of school.
3: /// </summary>
4: public class SchoolData
5: {
6: private int _id = -1;
7: public int ID
8: {
9: get { return this._id; }
10: set { this._id = value; }
11: }
12:
13: private string _name = String.Empty;
14: public string Name
15: {
16: get { return this._name; }
17: set { this._name = value; }
18: }
19:
20: private string _location = String.Empty;
21: public string Location
22: {
23: get { return this._location; }
24: set { this._location = value; }
25: }
26:
27: private string _zipCode = String.Empty;
28: public string ZipCode
29: {
30: get { return this._zipCode; }
31: set { this._zipCode = value; }
32: }
33:
34: private List<StudentData> _students = null;
35: public List<StudentData> Students
36: {
37: get { return ((this._students == null) ? this._students = new List<StudentData>() : this._students); }
38: }
39: }
40:
41: /// <summary>
42: /// The data class of student.
43: /// </summary>
44: public class StudentData
45: {
46: private int _id = -1;
47: public int ID
48: {
49: get { return this._id; }
50: set { this._id = value; }
51: }
52:
53: private string _name = String.Empty;
54: public string Name
55: {
56: get { return this._name; }
57: set { this._name = value; }
58: }
59:
60: private int _age = 0;
61: public int Age
62: {
63: get { return this._age; }
64: set { this._age = value; }
65: }
66:
67: private ScoreData _scores = null;
68: public ScoreData Scores
69: {
70: get { return this._scores; }
71: set { this._scores = value; }
72: }
73: }
74:
75: /// <summary>
76: /// The data class of score.
77: /// </summary>
78: public class ScoreData
79: {
80: private int _chinese = 0;
81: public int Chinese
82: {
83: get { return this._chinese; }
84: set { this._chinese = value; }
85: }
86:
87: private int _math = 0;
88: public int Math
89: {
90: get { return this._math; }
91: set { this._math = value; }
92: }
93:
94: private int _english = 0;
95: public int English
96: {
97: get { return this._english; }
98: set { this._english = value; }
99: }
100: }
我们先给出将要用到的这几个数据类,现在我们得为我们的例子准备点儿原始数据:
1: SchoolData redStarSchool
2: = new SchoolData {
3: ID = 1,
4: Name = "Red Star School",
5: Location = "Red Star Road, Beijing, China.",
6: ZipCode = "100000" };
7: redStarSchool.Students.Add(
8: new StudentData { ID = 1,
9: Name = "ZeroCool",
10: Age = 24,
11: Scores = new ScoreData { Chinese = 88, Math = 91, English = 93 } });
12: redStarSchool.Students.Add(
13: new StudentData {
14: ID = 2,
15: Name = "Frieda",
16: Age = 22,
17: Scores = new ScoreData { Chinese = 94, Math = 97, English = 96 } });
18: redStarSchool.Students.Add(
19: new StudentData {
20: ID = 3,
21: Name = "Michael",
22: Age = 23,
23: Scores = new ScoreData { Chinese = 67, Math = 74, English = 58 } });
好了,我们实例化了一个学校数据类示例,三个学生数据类示例(略去了班级和年级的概念)以及每个学生的三门成绩。原料已经有了,接下来我们看看怎么用这些相同的原料做出不同的菜肴来吧。
首先,我们要介绍几个最基本的查询操作符:
- from:与SQL命令中的from不同,查询表达式中的from更像是foreach,例如:
1: from student in redStarSchool.Students
- where:与SQL命令中的where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句,例如:
1: where student.Name == "ZeroCool"
- select:和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来,例如:
1: select student;
其实细心的朋友肯定已经发现了,上面三个关键字的示例代码连起来就正好是一句完整的查询表达式了:
1: IEnumerable<StudentData> students = from student in redStarSchool.Students
2: where student.Name == "ZeroCool"
3: select student;
这样,我们就从redStarSchool数据对象中找到了一个名为“ZeroCool”的学生的数据对象实例。至于你想用Func<TResult>委托类型或是扩展方法结合Lambda表达式的形式来翻译这段查询表达式也无所谓,关键是弄清楚查询操作符的含义与作用就行。上面的代码等效于:
1: // Using extension method.
2: IEnumerable<StudentData> students = redStarSchool.Students.Where(student => student.Name == "ZeroCool").Select(student => student);
3:
4: // Using Func<TResult>.
5: Func<StudentData, bool> filter = student => student.Name == "ZeroCool";
6: Func<StudentData, StudentData> result = student => student;
7:
8: IEnumerable<StudentData> students = redStarSchool.Students.Where(filter).Select(result);
接下来我们将会把精力主要放在介绍标准查询操作符而不是语法上,对语法还不太熟悉的朋友可以参考《C# 3.0 探索之旅》。
- orderby及orderby descending:对结果进行排序,默认是升序,加上descending表明采用降序,对应的扩展方法是OrderBy和OrderByDescending:
1: IEnumerable<StudentData> students = from student in redStarSchool.Students
2: where student.Age <= 23
3: orderby student.Age descending
4: select student;
5:
6: // The declaration above is equivalent to:
7: IEnumerable<StudentData> students
8: = redStarSchool.Students.Where(student => student.Age <= 23).OrderByDescending(student => student.Age).Select(student => student);
- Take:只返回限定数量的结果,在我们的数据中选择年龄小于等于23的结果应该有两个,但是我们如果只需要返回一个结果的话就可以用Take扩展方法来限定:
1: IEnumerable<StudentData> students
2: = redStarSchool.Students
3: .Where(student => student.Age <= 23)
4: .OrderByDescending(student => student.Age)
5: .Take(1)
6: .Select(student => student);
- Skip:跳过给定的数目返回后面的结果,例如我们还是查找年龄小于等于23的同学并根据讲叙排序,那么查询到的同学的名称依次是Michael和Frieda,如果我们要想跳过前面1个记录只返回后面的话(在这个例子中就是Frieda)就可以使用Skip扩展方法:
1: IEnumerable<StudentData> students
2: = redStarSchool.Students
3: .Where(student => student.Age <= 23)
4: .OrderByDescending(student => student.Age)
5: .Skip(1)
6: .Select(student => student);
- TakeWhile:该扩展方法将会用其判断条件去依次判断源序列中的元素,返回符合判断条件的元素,该判断操作将在返回false或源序列的末尾结束:
1: IEnumerable<StudentData> students
2: = redStarSchool.Students
3: .Where(student => student.Age <= 23)
4: .OrderByDescending(student => student.Age)
5: .TakeWhile(student => student.Scores.English < 60)
6: .Select(student => student);
- SkipWhile:该扩展方法和TakeWhile一样用判断条件去以此判断源序列中的元素并且跳过第一个符合判断条件的元素,一旦判断返回false,接下来将不再进行判断并返回剩下的所有元素:
1: IEnumerable<StudentData> students
2: = redStarSchool.Students
3: .Where(student => student.Age <= 23)
4: .OrderByDescending(student => student.Age)
5: .SkipWhile(student => student.Scores.English > 60)
6: .Select(student => student);
- Join:该扩展方法对两个序列中键匹配的元素进行inner join操作,例如:
1: var students = redStarSchool.Students
2: .Join(redStarSchool.Students,
3: student => student.Age > 21,
4: score => score.Scores.English > 60,
5: (student, score) => new { student.Name, score.Scores.English });
- GroupJoin:该扩展方法对两个序列中键匹配的元素进行grouped join操作,例如:
1: var students = redStarSchool.Students
2: .GroupJoin(redStarSchool.Students,
3: student => student.Age < 24,
4: score => score.Scores.English > 60,
5: (student, score) => new { student.Name, count = score.Sum(s => s.Scores.English) });
- Concat:很明显,这个扩展方法是对两个序列进行连接操作,例如:
1: IEnumerable<string> studentNames = redStarSchool.Students
2: .Select(student => student.ID.ToString())
3: .Concat(redStarSchool.Students.Select(student => student.Name));
- ThenBy/ThenByDescending:这两个扩展方式都是用在OrderBy/OrderByDescending之后的,第一个ThenBy/ThenByDescending扩展方法作为第二位排序依据,第二个ThenBy/ThenByDescending则作为第三位排序依据,以此类推,例如:
1: IEnumerable<StudentData> students = redStarSchool.Students
2: .Where(student => student.Age > 18)
3: .OrderBy(student => student.Age)
4: .ThenBy(student => student.Scores.Chinese);
- Reverse:该扩展方法用于将一个序列中的所有元素反向,例如:
1: IEnumerable<StudentData> students = redStarSchool.Students
2: .Where(student => student.Age > 18)
3: .OrderBy(student => student.Age)
4: .Reverse();
- GroupBy:分配并返回对传入参数进行分组操作后的可枚举对象,例如:
1: var students = redStarSchool.Students
2: .GroupBy(student => student.Scores.English > 60);
- Distinct:该扩展方法用于查询不重复的结果集,例如:
1: var students = redStarSchool.Students
2: .Select(student => student.Age)
3: .Distinct();
- Union:该扩展方法将两个序列进行合并操作,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age < 24)
3: .Select(student => student)
4: .Union(redStarSchool.Students.Where(student => student.Age == 24).Select(student => student));
- Intersect:该扩展方法先遍历第一个集合,找出所有唯一的元素,然后遍历第二个集合,并将每个元素与前面找出的元素作比对,返回所有在两个集合内都出现的元素,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age < 24)
3: .Select(student => student)
4: .Intersect(redStarSchool.Students.Where(student => student.Age < 23).Select(student => student));
- Except:该扩展方法先遍历第一个集合,找出所有唯一的元素,然后再遍历第二个集合,返回第二个集合中所有未出现在前面所得元素集合中的元素,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age < 24)
3: .Select(student => student)
4: .Except(redStarSchool.Students.Where(student => student.Age < 23).Select(student => student));
- AsEnumerable:该扩展方法不会改变其参数集合的类型,它只是用标准的查询操作符替换集合类型中自定义的查询操作符,例如,我们假设redStarSchool.Students是一个实现了自定义查询表达式的集合类型,而当我们想要用标准查询表达式对其进行操作时,则可以像下面代码这样:
1: var students = redStarSchool.Students
2: .AsEnumerable()
3: .Where(student => student.Age >= 23)
4: .Select(student => student.Name);
- ToArray:该扩展方法用于将结果集转换为Array类型,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age >= 23)
3: .Select(student => student.Name)
4: .ToArray();
- ToList:该扩展方法用于将结果集转换为List类型,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age >= 23)
3: .Select(student => student.Name)
4: .ToArray();
- ToDictionary:该扩展方法将结果集转换为Dictionary类型,并在其参数中设置Dictionary对象的Key,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age >= 23)
3: .Select(student => student.Name)
4: .ToDictionary(student => student.ToCharArray()[0]);
- ToLookup:该扩展方法用于从Dictionary对象中找到键与该扩展方法的参数相对应的那个键值对,常用于Join、GroupJoin和GroupBy操作返回的结果集,例如:
1: var students = redStarSchool.Students
2: .Join(redStarSchool.Students, name => name.Name == "ZeroCool", age => age.Age == 22, (student, age) => new { student.Name, age.Age })
3: .ToLookup(name => "ZeroCool");
- OfType:该扩展方法用于根据其参数所给定的类型来获取其所操作的数据集中的对应类型的元素,例如:
1: var students = redStarSchool.Students
2: .OfType<StudentData>();
- Cast:该扩展方法用于将所操作的集合中的元素转换成其指定的数据类型,例如:
1: var students = redStarSchool.Students
2: .Select(student => student.Age)
3: .Cast<double>();
- SequenceEqual:该扩展方法用于判断两个序列是否相等,如果不提供比较参数将会默认调用EqualityComparer<TSource>.Default,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age > 23)
3: .Select(student => student)
4: .SequenceEqual(redStarSchool.Students.Where(student => student.Age < 23).Select(student => student));
- First:该扩展方法返回集合中的一个元素,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age < 24)
3: .Select(classmate => classmate)
4: .First();
- FirstOrDefault:该扩展方法返回集合第一个元素,如果集合内没有元素则返回默认值,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age > 24)
3: .Select(classmate => classmate)
4: .FirstOrDefault();
- Last:该扩展方法返回集合中最后一个元素,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age < 24)
3: .Select(classmate => classmate)
4: .Last();
- LastOrDefault:该扩展方法返回集合中最后一个元素,如果集合中没有元素则返回默认值,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age > 24)
3: .Select(classmate => classmate)
4: .LastOrDefault();
- Single:该扩展方法返回集合中一个与其指定的条件相符的元素,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age < 24)
3: .Single(classmate => classmate.Name.Length == 6);
- SingleOrDefault:该扩展方法返回集合中一个与其指定的条件相符的元素,如果不存在这样的元素则返回默认值,例如:
1: var student = redStarSchool.Students
2: .Where(classmate => classmate.Age > 24)
3: .SingleOrDefault(classmate => classmate.Name == "ZeroCool");
- ElementAt:该扩展方法返回集合中指定索引(从0开始)处的元素,例如:
1: var students = redStarSchool.Students
2: .Select(student => student)
3: .ElementAt(1);
- ElementAtOrDefault:该扩展方法返回集合中指定索引处的元素,如果该元素不存在(如越界)则返回默认值,例如:
1: var students = redStarSchool.Students
2: .Select(student => student)
3: .ElementAtOrDefault(5);
- DefaultIfEmpty:该扩展方法为一个空集合提供一个默认元素,例如:
1: var students = redStarSchool.Students
2: .Where(student => student.Age > 25)
3: .Select(student => student.Name)
4: .DefaultIfEmpty();
- Range:该扩展方法用于获得一个整数类型的序列,例如:
1: var range = Enumerable.Range(0, 100);
- Repeat:该扩展方法用于获得一个重复指定次数的给定值的序列,例如:
1: var range = Enumerable.Repeat(1, 100);
- Empty:该扩展方法用于获得一个指定类型的空序列,例如:
1: var range = Enumerable.Empty<Int32>();
- Any:该扩展方法用于判断集合中是否存在满足条件的元素(若条件为空,则集合只要不为空就返回True,否则为False),例如:
1: bool hasFailedStudent = redStarSchool.Students
2: .Any(student => student.Scores.Chinese < 60 || student.Scores.Math < 60 || student.Scores.English < 60);
- All:该扩展方法用于判断集合中所有元素是否都满足条件,例如:
1: bool allSucceed = redStarSchool.Students
2: .All(student => student.Scores.Chinese >= 60 && student.Scores.Math >= 60 && student.Scores.English >= 60);
- Contains:该扩展方法判断元素中是否存在指定的元素,例如:
1: bool zerocoolExists = redStarSchool.Students
2: .Where(student => student.Age <= 24)
3: .Select(student => student.Name)
4: .Contains("ZeroCool");
- Count:该扩展方法用于统计集合中元素的个数,例如:
1: int englishSucceedAmount = redStarSchool.Students
2: .Count(student => student.Scores.English > 60);
- LongCount:对于元素个数较多的集合可视情况而选用LongCount来统计元素个数,其值为long型,例如:
1: long studentAmount = redStarSchool.Students.LongCount();
- Sum:该扩展方法用于对集合中数值类型元素求和,例如:
1: int englishScoreTotal = redStarSchool.Students
2: .Sum(englishScore => englishScore.Scores.English);
- Min:该扩展方法用于找出集合中数值最小的元素,例如:
1: int lowestEnglishScore = redStarSchool.Students
2: .Min(englishScore => englishScore.Scores.English);
- Max:该扩展方法用于找出集合中数值最大的元素,例如:
1: int highestEnglishScore = redStarSchool.Students
2: .Max(englishScore => englishScore.Scores.English);
- Average:该扩展方法对集合中的数值类型元素进行求平均值操作,其返回值类型为double,例如:
1: double averageEnglishScore = redStarSchool.Students
2: .Average(englishScore => englishScore.Scores.English);
- Aggregate:该扩展方法用遍历集合中的元素,并用一个种子值与当前元素通过某一指定的函数来进行对比,并保留符合条件的值,如果没有指定种子值的话,该扩展方法默认将集合的第一个元素作为种子值,例如:
1: int youngerStudentAmount = redStarSchool.Students
2: .Select(age => age.Age)
3: .Aggregate(21, (ageA, ageB) => ageA >= ageB ? ageA : ageB);
标准查询操作符就介绍到这里了,我相信各位朋友看了这篇文章中的介绍都已经领略到了LINQ的强大与适用,相信各位朋友通过实际动手练习,很快就能轻松自如地编写查询语句,并从中获得美妙的开发体验!
相关推荐
**LINQ标准查询操作符详解** 语言集成查询(LINQ)是.NET Framework 3.5引入的一项重要特性,它允许开发者使用类似SQL的语法在C#或VB.NET中进行强类型化的查询。LINQ的核心是它的标准查询操作符库,这些操作符提供...
### LINQ标准查询操作符详解 #### 一、投影操作符 **1. Select** - **定义**: `Select`操作符用于对集合中的每个元素应用指定的函数,并将结果返回为一个新的序列。此操作通常用来从原始数据集中提取特定属性或...
### LINQ标准查询操作符详解 #### 一、投影操作符 **1. Select** `Select` 操作符用于从源序列中选择一系列值,并将其转换为新的序列。这种转换通常涉及从源序列中的每个元素生成一个新元素。在 LINQ 查询中,`...
### LINQ标准查询操作符详解 #### 一、投影操作符 **1. Select** `Select` 是一种常用的投影操作符,它允许我们基于输入序列中的每个元素创建一个新序列。这种操作通常用来改变序列中元素的数据类型或者提取特定...
### LINQ的标准查询操作符详解 #### 一、概述 语言集成查询(Language Integrated Query,简称LINQ)是一项革命性的技术,它使得.NET Framework 3.5中的开发人员能够使用类似SQL的语言来查询数据,而不仅仅是关系型...
特别对LINQ在对象、XML、数据集和SQL上的应用进行了深入分析,详细讲解了这些应用可以使用的操作符和操作符原型,并分别给出使用这些操作符的示例和说明,以便读者理解和编写自己的LINQ代码。 《LINQ技术详解C#2008...
特别对LINQ在对象、XML、数据集和SQL上的应用进行了深入分析,详细讲解了这些应用可以使用的操作符和操作符原型,并分别给出使用这些操作符的示例和说明,以便读者理解和编写自己的LINQ代码。 本书可以为LINQ的...
Linq提供了丰富的查询操作符,如`Where()`(过滤)、`Select()`(映射)、`GroupBy()`(分组)、`OrderBy()`(排序)、`Join()`(连接)等。这些操作符可以组合使用,构建复杂的查询逻辑。 ### 4. Linq to Objects ...
- **标准查询操作符(Standard Query Operators)**:这是LINQ to Object中最核心的部分之一,它们是一系列扩展方法,定义在`System.Linq.Enumerable`类中。这些操作符允许开发者执行复杂的查询操作,如筛选(`Where`)...
特别对LINQ在对象、XML、数据集和SQL上的应用进行了深入分析,详细讲解了这些应用可以使用的操作符和操作符原型,并分别给出使用这些操作符的示例和说明,以便读者理解和编写自己的LINQ代码。 本书可以为LINQ的...
2. **查询操作符(Query Operators)**:LINQ定义了一系列的查询操作符,用于执行各种数据操作,如筛选、排序、分组等。 3. **扩展方法(Extension Methods)**:LINQ使用了C#中的扩展方法特性,使得静态方法可以像实例...
LINQ 的核心目标是提供一组标准查询操作符,这些操作符可以在 C# 和 VB.NET 等 .NET 编程语言中使用,从而使得查询数据变得更加简洁和直观。 #### 二、LINQ 的优势 1. **简化查询表达式**:LINQ 允许开发人员使用...
2. **查询操作符**:LINQ的方法语法由一系列链式调用的查询操作符组成,每个操作符执行特定的查询任务。例如,`Where`用于过滤数据,`Select`用于转换数据,`GroupBy`用于分组数据,`Join`用于联接数据,`OrderBy`和...
这个压缩包提供了各种LINQ操作符的实例,帮助开发者了解其功能和用法,从而提高代码的效率和可读性。 LINQ是一种在.NET框架中集成的数据查询语言,它允许开发者以更直观、类型安全的方式处理各种数据源,如数组、...
您可能感兴趣的文章:C#中Linq查询基本操作使用实例c#中LINQ的基本用法实例C# linq查询之动态OrderBy用法实例C#中的Linq Intersect与Except方法使用实例C#中的Linq to Xml详解LINQ 标准查询操作符linq语法基础使用...
通过本文介绍,我们详细了解了 LINQ to SQL 中的 Where 子句和 Select / Distinct 操作符的使用方法。这些概念和技巧对于编写高效、易于维护的数据库查询代码至关重要。理解并掌握这些知识可以帮助开发者更好地利用 ...
通过分析这些代码,我们可以深入了解LINQ的基本语法、查询操作符以及在不同数据源上的应用。 1. **LINQ的基本概念** - LINQ允许开发者使用统一的查询语法来操作各种类型的数据源,如数组、集合、数据库、XML等。 ...
- **查询操作符**:LINQ to Objects包含了一系列内置的操作符,如`Where()`, `Select()`, `OrderBy()`, `GroupBy()`等,这些操作符使得对数据集合的处理变得更加简单和灵活。 - **延迟执行**:LINQ to Objects采用...
因此,《LINQ技术详解C#2008版》并没有重点介绍无法应用于实际开发中的复杂的示例应用程序,而是重点介绍了每个LINQ操作符、方法或类。不过。在需要使用示例来真正演示一个问题时,也会恰如其分地出现一些比较复杂的...
特别对LINQ在对象、XML、数据集和SQL上的应用进行了深入分析,详细讲解了这些应用可以使用的操作符和操作符原型,并分别给出使用这些操作符的示例和说明,以便读者理解和编写自己的LINQ代码。 本书可以为LINQ的...