C# 中编写 LINQ 查询的三种方式:
// 查询语法 IEnumerable<int> filteringQuery = from num in numbers where num < 3 || num > 7 select num; // 方法语法. IEnumerable<int> largeNumbersQuery = numbers2.Where(c => c > 15);
//混合语法 int numCount1 = (from num in numbers1 where num < 3 || num > 7 select num).Count(); // Better: Create a new variable to store // the method call result IEnumerable<int> numbersQuery = from num in numbers1 where num < 3 || num > 7 select num; int numCount2 = numbersQuery.Count();
对查询子句的结果使用方法语法。 只需将查询表达式括在括号内,然后应用点运算符并调用此方法。
通常更好的做法是使用另一个变量(numCount2)来存储方法调用的结果。 这样就不太容易将查询本身与查询结果相混淆。
任何查询的类型都必须为 IEnumerable 或 IEnumerable<T>,或一种派生类型(如 IQueryable<T>)。 因此,返回查询的方法的任何返回值或 out 参数也必须具有该类型。
如果某个方法将查询具体化为具体的 List<T> 或 Array 类型,则认为该方法在返回查询结果(而不是查询本身)。 仍然能够编写或修改从方法返回的查询变量。
// QueryMethhod1 returns a query as its value. IEnumerable<string> QueryMethod1(ref int[] ints) { var intsToStrings = from i in ints where i > 4 select i.ToString(); return intsToStrings; } // QueryMethod2 returns a query as the value of parameter returnQ. void QueryMethod2(ref int[] ints, out IEnumerable<string> returnQ) { var intsToStrings = from i in ints where i < 4 select i.ToString(); returnQ = intsToStrings; }
查询基本上是一组有关如何检索和组织数据的指令。
若要执行查询,需要调用它的 GetEnumerator 方法。 当您使用 foreach 循环来循环访问元素时,将执行此调用。
若要计算查询和存储其结果,而不执行 foreach 循环,请对查询变量调用下列方法之一:
建议在存储查询结果时,将返回的集合对象分配给一个新变量,如下:
static List<int> numbers = new List<int>() { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; static void Main() { IEnumerable<int> queryFactorsOfFour = from num in numbers where num % 4 == 0 select num; // Store the results in a new variable // without executing a foreach loop. List<int> factorsofFourList = queryFactorsOfFour.ToList(); }
分组是 LINQ 最强大的功能之一。
下面的示例演示如何以各种方式对数据进行分组:
此外,最后两个查询将它们的结果投影到一个新的匿名类型中,该类型仅包含学生的名字和姓氏。
//单个属性作为组键对源元素进行分组 var queryLastNames = from student in students group student by student.LastName into newGroup orderby newGroup.Key select newGroup; 通过使用除对象属性以外的某个项作为组键对源元素进行分组, 在此示例中,键是学生姓氏的第一个字母 var queryFirstLetters = from student in students group student by student.LastName[0]; /* 通过使用某个数值范围作为组键对源元素进行分组。 然后,查询将结果投影到一个匿名类型中,该类型仅包含学生的名字和姓氏以及该学生所属的百分点范围。 使用匿名类型的原因是没有必要使用完整的 Student 对象来显示结果。*/ Helper method, used in GroupByRange. protected static int GetPercentile(Student s) { double avg = s.ExamScores.Average(); return avg > 0 ? (int)avg / 10 : 0; } var queryNumericRange = from student in students let percentile = GetPercentile(student) group new { student.FirstName, student.LastName } by percentile into percentGroup orderby percentGroup.Key select percentGroup; //通过使用布尔比较表达式对源元素进行分组 var queryGroupByAverages = from student in students group new { student.FirstName, student.LastName } by student.ExamScores.Average() > 75 into studentGroup select studentGroup; /* 下面的示例演示如何使用匿名类型来封装包含多个值的键。 在此示例中,第一个键值是学生姓氏的第一个字母。 第二个键值是一个布尔值,它指定该学生在第一次考试中的得分是否超过了 85。 可以按照该键中的任何属性对多组值进行排序。*/ var queryHighScoreGroups = from student in students group student by new { FirstLetter = student.LastName[0], Score = student.ExamScores[0] > 85 } into studentGroup orderby studentGroup.Key.FirstLetter select studentGroup;
参考
[1]MSDN,在C# 中编写 LINQ 查询
原文:http://www.cnblogs.com/ybtools/p/6524982.html