• 《LINQ技术详解C#》-2.查询表达式翻译为标准查询操作符


    (1)透明标识符

    有些翻译步骤要使用透明标识符(*)插入枚举变量。
    透明标识符只在翻译过程中存在,翻译结束将不再出现。

    (2)翻译步骤

    ①带有into连续语句的SelectGroup语句

    from...into...                  ->  from i in 
                                        from ...
                                        ...
    例如:  
    from c in customers                 from g in
    group c by c.Country into g     ->  from c in coustomers
    select new                          group c by c.Country
    {                                    select new   
        Country = g.Key,                 {
        CustCount = g.Count()             Country = g.Key, 
    }                                     CustCount = g.Count()
                                         }  
    

    最后的翻译为:

    customer.GroupBy(c=> c.Country)
        .Select( g=> new { Country = g.Key, CustCount = g.Count() })
    

    ②显示枚举变量类型

    2.1.如果查询表达式包含一个from语句,并且这条语句显示指定了一个枚举变量类型

    from T e in s                  ->     from e in s.Cast<T>()
    例如:
    
    from Customer c in customers   ->     from c in  customers.Cast<Customer>()
    select c
    

    最后结果:

    customers.Cast<Customer>()
    

    2.2.如果查询表达式包含一个join语句,并且这条语句显示指定一个枚举变量类型

    join T e n s                                    join e in s.Cast<T>()
    on k1 equals k2                         ->      on k1 equals k2  
    例如:
    
    from c in customers                             from c in customers  
    join Order o in orders                          join  o in orders.Cast<Order>()
    on c.CustomerID equals o.CustomerID     ->      on c.CustomerID equals o.CustomerID
    select new {                                    select new {
        c.Name,o.OrderDate,o.Tatal                      c.Name,o.OrderDate,o.Tatal 
    }                                               }
    

    最后的结果:

    customers
    .Join(orders.Cast<Order>(),
        c => c.CustomerID,
        o => o.CustomerID,
        (c,o) => new { c.Name,o.OrderDate,o.Tatal }
    )
    

    ③Join语句

    3.1.如果查询表达式包含一个from语句,后面跟一个join语句,但是在select语句没有使用into连续语句时,

    from e1 in s1							from t in s1
    join e2 in s2						->	.Join(s2,
    on k1 equals k2						 		  e1 => k1,
    select f									  e2 => k2,
    											(e1,e2) => f)
    										select t
    例如:
    from c in customers								from t in customers
    join o in orders								.Join(orders,
    on c.CustomerID equals o.CustomerID	->				c=>c.CustomerID,
    select new {                                    	o=>o.CustomerID,
        c.Name,o.OrderDate,o.Tatal                      (c,o) => new {
    }													c.Name,o.OrderDate,o.Tatal
    													}) select t
    

    最后的结果:

    cusotmers
    .Join(orders,
        c => c.CustomerID,
        o => o.CustomerID,
        (c,o) => new { c.Name,o.OrderDate,o.Tatal })
    

    3.2.如果表达式包含一个from,后面跟一个join语句,并且select语句后面带有into连续语句时,

    from e1 in s1						from t in s1
    join e2 in s2						.GroupJoin(s2,
    on k1 equals k2			->					   e1 => k1,
    into i										   e2 => k2,
    select f 									   (e1, i) => f)
    										select t
    

    例如:

    	from c in customers								from t in customers
    	join o in  orders								.GroupJoin(oders,
    	on c.CustomerID equals o.CustomerID					c => c.CustomerID,
    	into co								->			  o => o.CustomerID,
    	select new 											(c,co) => new 
    	{ c.Name, Sum => co.Sum(o => o.Total) }				{ c.Name,
    														Sum => co.Sum(
    														o => co.Total) }
    														select t
    

    最后的结果:

    cusotmers
    .GroupJoin(orders,
        c => c.CustomerID,
        o => o.CustomerID,
        (c,co) => new { c.Name, Sum =co.Sum(o = o.Tatal) })
    

    3.3.如果查询表达式包含一个from语句,后面跟一个join语句,并且在select语句之外的其他语句后面没有带into连续语句时,

    from e1 in s1						from * in
    join e2 in s2						from e1 in s1
    on k1 equals k2			->			from e2 in s2
    ...									on k1 equals k2
    									select new { e1, e2 }
    

      代码中有一个代码模式与这个翻译步骤中的第一个代码模式匹配。特别地,代码中还有一个查询表达式,该表达式包含一个from语句,后面一个join语句,并且select语句后面没有跟into连续语句。这样,编译器将重复这个翻译步骤

    3.4.如果查询表达式包含一个from 语句,后面一个join,并且在select语句之外的其他语句后带有into连续语句,

    from e1 in s1						from * in
    join e2 in s2						from e1 in s1
    on k1 equals k2			->			from e2 in s2
    into i								on k1 equals k2
    ...									into i
    									select new { e1,e2 }
    

    这次代码有一个模式与翻译步骤第二个代码模式匹配。特别地,代码中还有一个表达式,包含一个from语句,后面跟一个join语句,并且select语句后面带有一个into连续语句。这样编译器将重复这个翻译步骤。

    ④Let和Where语句

    4.1 Let语句

    from e in s					from * in
    let l = v				->  from e1 in s1
    							select new { e, l = v}
    

    例如,(t是一个编译器生成的标识符,对于编写的任何代码都是不可见和不可访问的)

    from c in  customers							from * in
    let cityStateZip = 								from c in customers
    	c.City + "," + c.State + " " + c.Zip  ->		select new {
    select new { c.Name , cityStateZip } 			 c,
    												 cityStateZip = 
    												c.City + "," + c.State + " " + c.Zip }
    												select new { c.Name , cityStateZip } 
    

    最后的结果:

    customers
    .Select(c => new { c , cityStateZip = c.City + "," + c.State + " " + c.Zip })
    .Select(c => new { t.c.Name, t.cityStateZip })
    

    4.2.查询表达式包含一个from,并紧跟一个where语句,

    from e in s				-> 		from e in s
    where w							.Where( e => w)
    

    例如:

    from c in customers					from c in customers
    where c.Country == "USA"		->	.Where(c => c.Country == "USA")
    select new { c.Name, c.Country}		select new { c.Name, c.Country }
    

    最后的结果:

    customers
    .Where(c => c.Country == "USA" )
    .Select(c => new { c.Name, c.Country })
    

    ⑤多个(From)语句

    5.1.如果查询表达式包含两个from语句,后面一个select语句

    from e1 in s1			from c in s1
    from e2 in s2		->	.SelectMany(e1 => from e2 in s2
    select f							select f )
    						select c
    

    例如:(t 是编译器临时产生的变量)

    from c in customers						from t in customers
    from o in c.Orders						.SelectMany(c => from o in c.Orders
    select new							->		select new { 
    { c.Name, o.OrderID, o.OrderDate }				c.Name, o.OrderID, o.OrderDate
    													})
    											select t
    

    最后的结果

    customers
    .SelectMany(c => c.Orders
    				.Select(o => new{ c.Name, o.OrderID, o.OrderDate }))
    

    5.2.如果查询表达式包含两个from语句,后面select之外的其他语句,

    	from e1 in s1				from * in
    	from e2 in s2				from e1 in s1
    	...					->		from e2 in s2
    								select new { e1 ,e2 }
    

    例如,

    from c in customers							from o in c.Orders
    from o in c.Orders							select new { c,o }
    orderby o.OrderDate descending		 ->		orderby o.OrderDate descending
    select new									select new
    	{ c.Name, o.OrderID, o.OrderDate }			{ c.Name, o.OrderID, o.OrderDate }
    

    最后的翻译:

    customers
    .SelectMany(c => c.Orders.Select(o => new { c,o }))
    .OrderByDescending(t => t.o.OrderDate)
    .Select(t => new { t.c.Name, t.o.OrderID, t.o,OrderDate })
    
  • 相关阅读:
    WPF之长短
    MFC程序和Win32程序的关系
    .NET Framework/CLR之长短
    常用软件
    经典推荐.Net面试法宝
    socket编程原理
    常用开发工具
    Get和Post方法的区别
    MAC IP等相关
    Datagrid为什么不自动换行显
  • 原文地址:https://www.cnblogs.com/tangge/p/8196441.html
Copyright © 2020-2023  润新知