LINQ项目-查询语法
查询表达式基于方法名称执行机械转换。所选择的查询操作符实现取决于所查询的变量类型以及范围内的扩展方法。
到目前为止,所展示的查询表达式只使用了一个生成器。如果使用多个生成器,则每个后续的生成器将在其前一个生成器的上下文中进行计算。例如,请考虑以下对查询的小修改:
如果运行以下输入数组:var query = from s1 in names where s1.Length == 5 from s2 in names where s1 == s2 select s1 + " " + s2;
我们将得到以下结果:string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" };
上述查询表达式扩展为以下点标记表达式:Burke Burke Frank Frank David David
请注意,使用 SelectMany 会导致内部查询表达式对外部结果失效。var query = names.Where(s1 => s1.Length == 5) .SelectMany(s1 => names.Where(s2 => s1 == s2) .Select(s2 => s1 + " " + s2) );
本部分前面所述的查询表达式的简化语法忽略了一个非常有用的功能。将一个查询的结果视为后续查询的生成器通常很有用。为此,查询表达式将使用 into 关键字在 select 或 group 子句后拼接一个新的查询表达式。下面是简化的语法,它展示 into 关键字如何适应其余的语法:
对于后续处理 group by 子句的结果,into 关键字特别有用。例如,请考虑以下程序:from itemName in srcExpr ((from itemName in srcExpr) | (where predExpr))* (orderby (keyExpr (ascending|descending)?)+)? ((select selExpr) | (group selExpr by keyExpr)) ( into itemName ((from itemName in srcExpr) | (where predExpr))* (orderby (keyExpr (ascending|descending)?)+)? ((select selExpr) | (group selExpr by keyExpr)) )*
该程序将输出以下内容:var query = from item in names orderby item group item by item.Length into lengthGroups orderby lengthGroups.Key descending select lengthGroups; foreach (var group in query) { Console.WriteLine("Strings of length {0}", group.Key); foreach (var val in group.Group) Console.WriteLine(" {0}", val); }
本部分描述 C# 如何实现查询表达式。其他语言可能选择通过显式语法支持其他查询操作符。Strings of length 7 Everett Strings of length 6 Albert Connor George Harris Strings of length 5 Burke David Frank
需要注意的是,查询语法绝对不是硬连接到标准查询操作符的。它是纯粹的语法功能,通过以适当的名称和签名实现基础方法,来应用于任何符合 LINQ 样式 的类型。上述标准查询操作符是使用扩展方法增加 IEnumerable 接口来实现这一点的。开发人员可以对任何所需的类型使用查询语法,只要确保它符合 LINQ 样式(通过直接实现必需的方法,或者将它们添加为扩展方法)即可。
这种可扩展性在 LINQ 项目本身中采用,方法是:提供两个支持 LINQ 的 API,分别名为 DLinq(为基于 SQL 的数据访问实现 LINQ 样式)和 Xlinq(允许 LINQ 通过 XML 数据查询)。这两者将在以下部分中描述。
0
相关文章