跳转至

查询语法⚓︎

一、获取数据源⚓︎

LINQ 通过 from 子句引入数据源和范围变量,范围变量将充当对数据源中每个连续的元素的引用。

//queryAllCustomers is an IEnumerable<Customer>
var queryAllCustomers = from cust in customers select cust;

Note

对于非泛型数据源,如ArrayList,必须显式键入范围变量类型, var query = from Student s in arrList

二、筛选⚓︎

LINQ 通过 where 子句构造筛选器,筛选器使查询仅返回表达式为 true 的元素。

var queryLondonCustomers = from cust in customers
                           where cust.City == "London" // 筛选器
                           select cust;

可以使用C#中的逻辑运算符对多个筛选表达式进行组合:

where cust.City == "London" && cust.Name == "Devon"

where cust.City == "London" || cust.City == "Paris"

三、排序⚓︎

LINQ 通过 orderby 子句对结果进行升序(ascending,默认值)或降序(descending)排序,以及次要排序。

IEnumerable<Country> querySortedCountries =
    from country in countries
    orderby country.Area, country.Population descending // Area 主要排序,Population 次要
    select country;

四、分组⚓︎

LINQ 通过 group ... by ... 子句生成按指定键组织的组的序列,键可以是任何数据类型。

var queryCountryGroups =
    from country in countries
    group country by country.Name[0];

五、联接⚓︎

LINQ 通过 join 子句实现基于每个元素中指定的键之间的相等比较,将一个数据源中的元素与另一个数据源中的元素进行关联 and/or 合并。

联接了两个序列之后,必须使用 select 或 group 语句指定要存储在输出序列中的元素。 还可以使用匿名类型将每组关联元素中的属性合并到输出序列的新类型中。

var categoryQuery =
    from cat in categories
    join prod in products 
    on cat equals prod.Category
    select new
    {
        Category = cat,
        Name = prod.Name
    };
// 示例关联其 Category 属性与 categories 字符串数组中一个类别匹配的 prod 对象。 筛选出 Category 与 categories 中的任何字符串均不匹配的产品。select 语句投影属性取自 cat 和prod 的新类型。

六、投影⚓︎

LINQ 通过 select 子句生成查询结果并指定每个返回的元素的“形状”或类型。当 select 子句生成除源元素副本以外的内容时,该操作称为投影或选择。 使用投影转换数据是 LINQ 查询表达式的一种强大功能。

Note

查询表达式必须以 from 子句开头,必须以 group 子句或 select 子句结尾。

七、临时存储⚓︎

在查询表达式中,存储子表达式的结果有时很有帮助,可在后续子句中使用。LINQ 通过 let 子句执行此操作,该关键字创建一个新的范围变量并通过提供的表达式结果初始化该变量。 

使用值进行初始化后,范围变量不能用于存储另一个值。 但是,如果范围变量持有可查询类型,则可以查询该变量。

string[] names = { 
    "Svetlana Omelchenko", 
    "Claire O'Donnell", 
    "Sven Mortensen", 
    "Cesar Garcia" 
};
IEnumerable<string> queryFirstNames =
    from name in names
    let firstName = name.Split(' ')[0]
    select firstName;

foreach (string s in queryFirstNames)
{
    Console.Write(s + " ");
}

//Output: Svetlana Claire Sven Cesar

八、子查询⚓︎

查询子句本身可能包含查询表达式,这有时称为子查询。 每个子查询都以自己的 from 子句开头,该子句不一定指向第一个 from 子句中的相同数据源。

var queryGroupMax =
    from student in students
    group student by student.Year into studentGroup
    select new
    {
        Level = studentGroup.Key,
        HighestScore = ( // 子查询
            from student2 in studentGroup
            select student2.ExamScores.Average()
        ).Max()
    };