八大子句
LINQ查询子句概述
1.查询(Query)是一组指令,这些指令可以从一个或多个给定的数据源中检索数据,并指定检索结果的数据类型和表现形式。
2.查询表达式是一种查询语法表示的表达式,由一组用类似于SQL的声明性语法编写的子句组成。
3.每一个字句可以包含一个或多个C#表达式,而这些表达式本身又可能是查询表达式或包含查询表达式。
4.查询表达式和其他表达式一样,可以用在C#表达式有效的任何上下文中。
子句说明
- LINQ查询表达式必须以from子句开头,并且必须以select或group子句结束。
- 在第一个from子句和最后一个select或group子句之间,查询表达式可以包含一个或多个where、orderby、group、join、let子句,甚至from子句。
- 另外,join和group子句还可以使用into子句指定临时标识符号
数据库查询子句:
1. from...in子句:指定查询操作的数据源和范围变量
在 LINQ 查询中,第一步是指定数据源。像在大多数编程语言中一样,在 C# 中,必须先声明变量,才能使用它。在 LINQ 查询中,最先使用 from 子句的目的是引入数据源 ( customers) 和范围变量 ( cust)。
//queryAllCustomers is an IEnumerable<Customer>
var queryAllCustomers = from cust in customers
select cust;
2. select子句:指定查询结果的类型和表现形式
在查询表达式中, select 子句可以指定将在执行查询时产生的值的类型。 该子句的结果将基于前面所有子句的计算结果以及 select 子句本身中的所有表达式。 查询表达式必须以 select 子句或 group 子句结束。
class SelectSample1
{
static void Main()
{
//Create the data source
List<int> Scores = new List<int>() { 97, 92, 81, 60 };
// Create the query.
IEnumerable<int> queryHighScores =
from score in Scores
where score > 80
select score;
// Execute the query.
foreach (int i in queryHighScores)
{
Console.Write(i + " ");
}
}
}
//Output: 97 92 81
3. where子句:筛选元素的逻辑条件,一般由逻辑元算符组成
where 子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素。 它将一个布尔条件(“谓词”)应用于每个源元素(由范围变量引用),并返回满足指定条件的元素。一个查询表达式可以包含多个 where 子句,一个子句可以包含多个谓词子表达式。
class WhereSample
{
static void Main()
{
// Simple data source. Arrays support IEnumerable<T>.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// Simple query with one predicate in where clause.
var queryLowNums =
from num in numbers
where num < 5
select num;
// Execute the query.
foreach (var s in queryLowNums)
{
Console.Write(s.ToString() + " ");
}
}
}
//Output: 4 1 3 2 0
4. group...by子句:对查询进行分组
使用 group 子句,您可以按指定的键分组结果。
// queryCustomersByCity is an IEnumerable<IGrouping<string, Customer>>
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
// customerGroup is an IGrouping<string, Customer>
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
在使用 group 子句结束查询时,结果采用列表的列表形式。 列表中的每个元素是一个具有 Key 成员及根据该键分组的元素列表的对象。 在循环访问生成组序列的查询时,您必须使用嵌套的 foreach 循环。 外部循环用于循环访问每个组,内部循环用于循环访问每个组的成员。
5. orderby子句:对查询结果进行排序,可以为“升序”或“降序”
在查询表达式中, orderby 子句可使返回的序列或子序列(组)按升序或降序排序。 可以指定多个键,以便执行一个或多个次要排序操作。排序是由针对元素类型的默认比较器执行的。默认排序顺序为升序。
class OrderbySample1
{
static void Main()
{
// Create a delicious data source.
string[] fruits = { "cherry", "apple", "blueberry" };
// Query for ascending sort.
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;
// Query for descending sort.
IEnumerable<string> sortDescendingQuery =
from w in fruits
orderby w descending
select w;
// Execute the query.
Console.WriteLine("Ascending:");
foreach (string s in sortAscendingQuery)
{
Console.WriteLine(s);
}
// Execute the query.
Console.WriteLine(Environment.NewLine + "Descending:");
foreach (string s in sortDescendingQuery)
{
Console.WriteLine(s);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Ascending:
apple
blueberry
cherry
Descending:
cherry
blueberry
apple
*/
6. join子句:连接多个查询操作的数据源
使用 join 子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。 唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。例如,食品经销商可能具有某种产品的供应商列表以及买主列表。例如,可以使用 join 子句创建该产品同一指定地区供应商和买主的列表。
join 子句接受两个源序列作为输入。 每个序列中的元素都必须是可以与另一个序列中的相应属性进行比较的属性,或者包含一个这样的属性。join 子句使用特殊的 equals 关键字比较指定的键是否相等。 join 子句执行的所有联接都是同等联接。 join 子句的输出形式取决于所执行的联接的具体类型。 以下是三种最常见的联接类型:
内部联接
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence
分组联接
var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };
左外部联接
var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0})
select new { CatName = category.Name, ProdName = item.Name };
7. let子句:引入用于存储查询表达式中的子表达式结果的范围变量
在查询表达式中,存储子表达式的结果有时很有用,这样可以在随后的子句中使用。可以使用 let 关键字完成这一工作,该关键字可以创建一个新的范围变量,并且用您提供的表达式的结果初始化该变量。 一旦用值初始化了该范围变量,它就不能用于存储其他值。但如果该范围变量存储的是可查询的类型,则可以对其进行查询。
class LetSample1
{
static void Main()
{
string[] strings =
{
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
};
// Split the sentence into an array of words
// and select those whose first letter is a vowel.
var earlyBirdQuery =
from sentence in strings
let words = sentence.Split(' ')
from word in words
let w = word.ToLower()
where w[0] == 'a' || w[0] == 'e'
|| w[0] == 'i' || w[0] == 'o'
|| w[0] == 'u'
select word;
// Execute the query.
foreach (var v in earlyBirdQuery)
{
Console.WriteLine("\"{0}\" starts with a vowel", v);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
"A" starts with a vowel
"is" starts with a vowel
"a" starts with a vowel
"earned." starts with a vowel
"early" starts with a vowel
"is" starts with a vowel
*/
8. into子句:提供一个临时标示符,充当对join、group或select子句的结果
引用组操作的结果,可以使用 into 关键字来创建可进一步查询的标识符。 下面的查询只返回那些包含两个以上的客户的组:
// custQuery is an IEnumerable<IGrouping<string, Customer>>
var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;