C# 回顾之 查询表达式
2021-01-19 19:11
标签:div -o res query HERE 介绍 有用 缩减 equal 目录 查询表达式 (query expression) 为查询提供一种类似于关系和分层查询语言(如 SQL 和 XQuery)的语言集成语法。 query-expression from-clause query-body query-body-clauses query-body-clause let-clause where-clause join-clause join-into-clause orderby-clause orderings ordering-direction select-or-group-clause select-clause group-clause query-continuation C# 语言不指定查询表达式的执行语义。而是将查询表达式转换为遵循查询表达式模式的方法调用。具体而言,查询表达式将转换为对具有以下名称的方法的调用:Where、Select、SelectMany、Join、GroupJoin、OrderBy、OrderByDescending、ThenBy、ThenByDescending、GroupBy 和 Cast。 显式范围变量类型对于查询实现非泛型 IEnumerable 接口的集合很有用,但对于实现泛型 IEnumerable 显式指定范围变量类型的 from 子句 显式指定范围变量类型的 join 子句 转换查询没有显式范围变量类型 退化查询表达式是平常选择源的元素的查询表达式。后面的转换阶段会移除由其他转换步骤引入的退化查询,方法是用其源替换这些退化查询。 带有另一个 from 子句且后接一个 select 子句的查询表达式 带有另一个 from 子句且后接除 select 以外的任何子句的查询表达式 带有 let 子句的查询表达式 带有 where 子句的查询表达式 带有 join 子句(不含into)且后接select 子句的查询表达式 带有 join 子句(不含 into)且后接除 select 子句之外的其他内容的查询表达式 带有 join 子句(含 into)且后接 select 子句的查询表达式 带有 join 子句(含into)且后接除select 子句之外的其他内容的查询表达式 带有 orderby 子句的查询表达式 查询表达式模式 (Query expression pattern) 建立了一种方法模式,类型可以实现该模式来支持查询表达式。因为查询表达式通过句法映射转换为方法调用,所以类型在如何实现查询表达式模式方面具有很大灵活性。 支持查询表达式模式的泛型类型 C C# 回顾之 查询表达式 标签:div -o res query HERE 介绍 有用 缩减 equal 原文地址:https://www.cnblogs.com/HavenLau/p/12152896.html
1. 查询表达式
2. 分类
from-clause query-body
from typeopt identifier in expression
query-body-clausesopt select-or-group-clause query-continuationopt
query-body-clause
query-body-clauses query-body-clause
from-clause
let-clause
where-clause
join-clause
join-into-clause
orderby-clause
let identifier = expression
where boolean-expression
join typeopt identifier in expression on expression equals expression
join typeopt identifier in expression on expression equals expression into identifier
orderby orderings
ordering
ordering,ordering
ascending
descending
select-clause
group-clause
select expression
group expression by expression
into identifier query-body
3. 多义性
4. 转换
4.1 转换规则
4.2 转换示例
1. 带继续符的查询表达式
from … into x …
转换为
from x in (from … ) …
from c in customers
group c by c.Country into g
select new {Country = g.key,CustCount = g.Count()}
转换为
from g in
from c in customers
group c by c.Country
select new {Country = g.key,CustCount = g.Count()}
最终转换为
customers.
GroupBy(c=>c.Country)
Select(g=>new { Country = g.key,CustCount = g.Count() })
2. 显示范围变量类型
from T x in e
转换为
from x in ( e ) . Cast ( )
join T x in e on k1 equals k2
转换为
join x in ( e ) . Cast ( ) on k1 equals k2
from Customer c in customers
where c.City == "London"
select c
转换为
from c in customers.Cast
3. 退化查询表达式
from x in e select x 转换为 ( e ) . Select ( x => x )
from c in customers select c 转换为 customers.Select(c=>c)
4. from、let、where、join和orderby子句
from x1 in e1
from x2 in e2
select v
转换为
( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )
from x1 in e1
from x2 in e2
…
转换为
from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )
…
from x in e
let y = f
…
转换为
from * in ( e ) . Select ( x => new { x , y = f } )
…
from x in e
where f
…
转换为
from x in ( e ) . Where ( x => f )
…
from x1 in e1
join x2 in e2 on k1 equals k2
select v
转换为
( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )
from x1 in e1
join x2 in e2 on k1 equals k2
…
转换为
from * in ( e1 ) . Join(
e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
…
from x1 in e1
join x2 in e2 on k1 equals k2 into g
select v
转换为
( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )
from x1 in e1
join x2 in e2 on k1 equals k2 into g
…
转换为
from * in ( e1 ) . GroupJoin(
e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
…
from x in e
orderby k1 , k2 , … , kn
…
转换为
from x in ( e ) .
OrderBy ( x => k1 ) .
ThenBy ( x => k2 ) .
… .
ThenBy ( x => kn )
…
5. 示例
from c in customers
from o in c.Orders
select new { c.Name, o.OrderID, o.Total }
转换为
customers.
SelectMany(c => c.Orders,
(c,o) => new { c.Name, o.OrderID, o.Total }
)
from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }
转换为
from * in customers.
SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }
其最终转换为
customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.OrderID, x.o.Total })
from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new { o.OrderID, Total = t }
转换为
from * in orders.
Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) })
where t >= 1000
select new { o.OrderID, Total = t }
其最终转换为
orders.
Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) }).
Where(x => x.t >= 1000).
Select(x => new { x.o.OrderID, Total = x.t })
from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new { c.Name, o.OrderDate, o.Total }
转换为
customers.Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c.Name, o.OrderDate, o.Total })
from c in customers
join o in orders on c.CustomerID equals o.CustomerID into co
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }
转换为
from * in customers.
GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
(c, co) => new { c, co })
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }
其最终转换为
customers.
GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
(c, co) => new { c, co }).
Select(x => new { x, n = x.co.Count() }).
Where(y => y.n >= 10).
Select(y => new { y.x.c.Name, OrderCount = y.n)
from o in orders
orderby o.Customer.Name, o.Total descending
select o
具有最终转换
orders.
OrderBy(o => o.Customer.Name).
ThenByDescending(o => o.Total)
6. select子句
from x in e select v
转换为
( e ) . Select ( x => v )
当 v 为标识符 x 时,转换仅为
( e )
from c in customers.Where(c => c.City == “London”)
select c
仅转换为
customers.Where(c => c.City == “London”)
7. groupby子句
from x in e group v by k
转换为
( e ) . GroupBy ( x => k , x => v )
当 v 为标识符 x 时,转换为
( e ) . GroupBy ( x => k )
from c in customers
group c.Name by c.Country
转换为
customers.
GroupBy(c => c.Country, c => c.Name)
8. 透明标识符
from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }
转换为
from * in customers.
SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }
进一步转换为
customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(* => o.Total).
Select(* => new { c.Name, o.Total })
在清除透明标识符后等效于
customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.Total })
from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }
转换为
from * in customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o })
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }
进一步缩减为
customers.
Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }).
Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d }).
Join(products, * => d.ProductID, p => p.ProductID, (*, p) => new { *, p }).
Select(* => new { c.Name, o.OrderDate, p.ProductName })
其最终转换为
customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o }).
Join(details, x => x.o.OrderID, d => d.OrderID,
(x, d) => new { x, d }).
Join(products, y => y.d.ProductID, p => p.ProductID,
(y, p) => new { y, p }).
Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })
5.模式
delegate R Func
上一篇:C#反射与特性(二):探究反射