zoukankan      html  css  js  c++  java
  • Linq Coding Part Nine(IEnumerable、IQueryable、Set)

          Enumerable 是 .NET FX 3.5 System.Linq 中新增的类型,实现了大量 IEnumerable<T> 扩展方法, 所有直接或间接实现该接口的类型都可以使用 Linq to Object 语法; 而 Queryable 则针对 IQueryable<T> 扩展,主要用于 DLinq 的操作,IQueryable<T> 继承自 IEnumerable<T>。

    提供对未指定数据类型的特定数据源的查询进行计算的功能。 IQueryable 接口由查询提供程序实现。 该接口只能由同时实现 IQueryable<(Of <(T>)>) 的提供程序实现。 如果该提供程序不实现 IQueryable<(Of <(T>)>),则无法对提供程序数据源使用标准查询运算符。 IQueryable 接口继承 IEnumerable 接口,以便在前者表示一个查询时可以枚举该查询的结果。 枚举强制执行与 IQueryable 对象关联的表达式目录树。 “执行表达式目录树”的定义是查询提供程序所特有的。

    例如,它可能涉及将表达式目录树转换为适用于基础数据源的查询语言。

    在调用 Execute 方法时将执行不返回可枚举结果的查询。

    IEnumerable和IQueryable的区别:

        In one of our current projects we're using LINQ TO SQL to conquer the object-relational impedance mismatch. We all had some experience with LINQ and deferred execution. But it was getting obvious that we all needed to deeply internalize the difference between IEnumerable and IQueryable. 
        EntitySet<T> and Table<T> both implement the IEnumerable<T> interface. However, if there would not be IQueryable all querying functionality - including filtering and sorting - would be executed on the client. To optimize a query for a specific data source we need a way to analyze a query and its definition. That’s where expression trees are coming in. As we know an expression tree represents the logical definition of a method call which can be manipulated and transformed. 
        So we have a mutable logical definition of our query on one side and a queryable data source on the other. The Property Provider on IQueryable now returns an IQueryProvider which is exactly what we need here. 

    Code


          There are 2 interesting operations and their generic counterparts. The generic versions are used most of the time and they perform better because we can avoid using reflection for object instantiation. CreateQuery() does precisely what we are looking for. It takes an expression tree as argument and returns another IQueryable based on the logical definition of the tree. When the returned IQueryable is enumerated it will invoke the query provider which will then process this specific query expression. 
        The Execute() method now is used to actually executing your query expression. This explicit entry point – instead of just relying on IEnumerator.GetEnumerator() – allows executing ET’s which do not necessarily yield sequences of elements. (For example aggregate functions like count or sum.) 
        We finally have our two worlds nicely connected together. The mutability of ET and the deferred execution of IEnumerable combined to a construct that can analyze an arbitrary mutated and extended query at the last possible moment and execute an optimized query against its data source. It’s not even too hard to implement your own IQueryProvider for your own data source. Maybe I’ll cover that in a later post. This is really nice work Eric Meijer and his team has done here.

         明白了以两者的区别和概念之后,下面再来以直观的代码方式看看有关于LINQ Set操作几个扩展方法 

     1  List<Int32> numbers = new List<Int32> { 2126523621956456456535236 };
     2 
     3  List<Int32> numbersTwo = new List<Int32> { 21456535236 };
     4 
     5         /// <summary>
     6         /// 列出回序列中的非重复元素。        
     7          /// </summary>
     8         public void Distinct()
     9         {
    10             IEnumerable<Int32> distinctNumbers = numbers.Distinct();
    11 
    12             //IQueryable<Int32> distinctNumbers = numbers.AsQueryable().Distinct();
    13  
    14             Console.WriteLine("Distinct numbers:");
    15  
    16             foreach (Int32 number in distinctNumbers)
    17             {
    18                 Console.WriteLine(number);
    19             }
    20         }
    21 
    22         /// <summary>
    23         /// 列出的序列只显示在第一个序列中的元素。
    24          /// </summary>
    25         public void Except()
    26         {
    27             IEnumerable<Int32> exceptNumbers = numbers.Except(numbersTwo);
    28 
    29             //IQueryable<Int32> execeptNumbers = numbersTwo.AsQueryable().Except(numbers);
    30  
    31             Console.WriteLine("Except numbers:");
    32 
    33             foreach (Int32 number in exceptNumbers)
    34             {      
    35                 Console.WriteLine(number);
    36             }
    37         }
    38 
    39         /// <summary>
    40         /// 进行比较生成两个序列的交集。
    41          /// </summary>
    42         public void Intersect()
    43         {
    44             IEnumerable<Int32> intersectNumbers = numbers.Intersect(numbersTwo);
    45 
    46             //IQueryable<Int32> intersectNumbers = numbersTwo.AsQueryable<Int32>()
    47                                                              .Intersect(numbers);
    48 
    49             Console.WriteLine("Intersect numbers:");
    50 
    51             foreach (Int32 number in intersectNumbers)
    52             {
    53                 Console.WriteLine(number);
    54             }
    55         }
    56 
    57         /// <summary>
    58         /// 执行的联合操作。返回的序列包含两个输入序列的唯一的元素。
    59          /// </summary>
    60         public void Union()
    61         {
    62             IEnumerable<Int32> unionNumbers = numbers.Union(numbersTwo);
    63 
    64             //IQueryable<Int32> unionNumbers = numbersTwo.AsQueryable().Union(numbers);
    65  
    66             Console.WriteLine("Union numbers:");
    67  
    68             foreach (Int32 number in unionNumbers)
    69             {
    70                 Console.WriteLine(number);
    71             }
    72         }
    73  
    74         /// <summary>
    75         /// 连接两个序列。
    76          /// </summary>
    77         public void Concat()
    78         {
    79             IEnumerable<Int32> concatNumbers = numbers.Concat(numbersTwo);
    80 
    81             //IQueryable<Int32> concatNumbers = numbersTwo.AsQueryable().Concat(numbers);
    82  
    83             Console.WriteLine("Concat numbers:");
    84 
    85             foreach (Int32 number in concatNumbers)
    86             {
    87                 Console.WriteLine(number);
    88             }
    89         }

     

    LINQ Coding 目录

    More Linq Coding

  • 相关阅读:
    关于C语言中类型的理解,有符号无符号的理解以及浮点数的理解
    关于集中注意力,情绪管理,记忆的总结整体
    关于链表逆置的问题
    git中reset和checkout的总结整理
    git中关于分支和stash的理解
    SVN和git的区别
    shell命令之find的用法
    (转载)获取服务器响应时间
    (转载)Spring定时任务的几种实现
    (转载)spring单例和多例详解。如何在单例中调用多例对象
  • 原文地址:https://www.cnblogs.com/RuiLei/p/1307556.html
Copyright © 2011-2022 走看看