zoukankan      html  css  js  c++  java
  • 《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 })
    
  • 相关阅读:
    [JSOI2007][BZOJ1031] 字符加密Cipher|后缀数组
    leetcode Flatten Binary Tree to Linked List
    leetcode Pascal's Triangle
    leetcode Triangle
    leetcode Valid Palindrome
    leetcode Word Ladder
    leetcode Longest Consecutive Sequence
    leetcode Sum Root to Leaf Numbers
    leetcode Clone Graph
    leetcode Evaluate Reverse Polish Notation
  • 原文地址:https://www.cnblogs.com/tangge/p/8196441.html
Copyright © 2011-2022 走看看