.NET LINQ 查询

概述

什么是Linq表达式?什么是Lambda表达式?

事实上,对于LINQ to Objects来说,就是通过为IEnumerable<T>接口定义了一组约50个扩展方式来实现的。

Lambda表达式(拉姆达表达式,Lambda Expression)

   匿名方法是在C#2.0中引入的。在C#3.0中,又引入了一种Lambda表达式的语法,可以将它视为匿名方法的等价物,但是语法更为简洁,使得匿名方法的编写变得更加方便。

  对于一些扩展方法,它的返回值也是IEnumerable<T>类型,这意味着可以进行一种链式的方法调用,例如list.Where().Orderby().Select().ToList()。 每调用一次,就对列表进行了一次加工。

  C#专门为LINQ提供了一种称做查询表达式(Query Expression)的语法,该语法编译后就相当于调用上小节提到的扩展方法。 一个简单的查询表达式如下:

//获得集合,本章将会多次出现
static ProductCollection col = Product.GetSampleCollection();
            static void Main(string[] args)
            {
                var query = from x in col
                            where x.Category == "Beer"
                            orderby x.Code
                            select new { Title = x.Name.ToUpper(), Code = x.Code };
                foreach (var item in query)
                {
                    Console.WriteLine("{0}, {1}", item.Code, item.Title);
                }
            }

   在这个查询表达式中,from声明了一个范围变量(range variable)x;in关键字后面是要查询的数据源col;where后面是筛选的依据,为Lambda表达式;最后select投影操作创建了一个新的匿名类型。

与这个查询表达式相对应的链式方法调是这样:

var query = col
       .Where(x => x.Category == "Beer")
        .OrderBy(x => x.Code)
        .Select(x => new { Title = x.Name.ToUpper(), Code = x.Code });

   查询表达式和方法调用可以混合使用,因此,上面的语句也可以这样写:

var query = from x in col.where(x => x.Category == "Beer")
       orderby x.Code
       select new { Title = x.Name.ToUpper(), Code = x.Code };

一般来说,有这样两种策略:

  1)只使用链式方法调用。 但在个别情况下,比如两个集合的连接操作中,使用链式方法调用会使语句变得很复杂,此时应混合使用查询表达式。

  2)只使用查询表达式。 但对于某些查询表达式不支持的操作,例如Concat(),混合使用方法调用。

笔者采用的是是第一种策略,因为方法调用更为基础,查询表达式能实现的功能,方法调用全都能实现,而且在大多数情况下使用起来并没有太多不便之处。

-----

1.Where()

2.OfType()
OfType()方法也用于筛选。 与其他运算符不同的是,OfType()定义在IEnumerable上,而不是IEnumerable<T>,它的作用是从非泛型集合中筛选出某一类型的成员并返IEnumerable<T>。

因为OfType()返回的是IEnumerable<T>,所以返回的结果可以继续调用其他的LINQ运算符。

 ArrayList list = new ArrayList();
            list.Add(100);
            list.Add(DateTime.Now);
            list.Add("Have fun");
            list.Add("Intresting");
            var query = list.OfType<string>().Where(x => x.StartsWidth("Have"));//输出:Have fun

3.Cast()
与OfType()类似,Cast()也定义在IEnumerable上,它用于将非泛型的序列转换为泛型序列IEnumerable<T>。 当某一序列项无法成功转换时,则会抛出异常:

ArrayList list = new ArrayList();
            list.Add(100);
            list.Add("Have fun");
            var query = list.Cast<int>(); //异常: System.InvalidCastException: 指定的转换无效

4.OrderBy()--OrderByDescending()

var query = col.OrderBy(x => x.Category);

ThenBy()--ThenByDescending()

var query = col.OrderBy(x => x.Category).ThenBy(x => x.Price);

5.Select()

Select()运算符在上面也出现过,它实现了一种投影操作,可以进行对象类型转换。

var query = col.Select((x, index) => new { Title = x.Name, Index = index, Price = x.Price

6.Take()Skip()

Take()运算符返回了由原序列中前N个元素构成的新序列,N由参数指定。

var query = col.Take(3); // 返回前3个元素

Skip()运算符和Take()正好相反,它跳过N个元素,返回后面的所有元素构成的序列:

var query = col.Skip(3); // 返回第3个元素之后的所有元素

Skip()和Take()结合起来也可以进行分页,例如,每页显示20条数据,显示第2页的数据,可以这样编写代码:

var query = col.Skip(20).Take(20);

7.TakeWhile()SkipWhile()

TakeWhile()和Where()有点类似,只不过当Where()遇到不符合条件的元素时,会继续查找序列中满足条件的下一个元素,直到序列结束。

而TakeWhile()在遇到不符合条件的元素时会直接返回前面找到的满足条件的元素。

int[] array = { 1, 2, 10, 4, 5};
var query = array.TakeWhile(x => x <= 5); // 输出1,2

SkipWhile()是TakeWhile()的反操作,它会一直跳过符合条件的元素,直到遇到第一个不符合条件的元素,然后返回该元素之后的所有元素构成的序列。

int[] array = { 1, 2, 10, 4, 5};
var query = array.SkipWhile(x => x <= 5); // 输出10,4,5
query.ShowConsole();

8.Reverse()

Reverse()用于将序列中的元素逆序排列,例如:

int[] array = { 1, 2, 3};
var query = array.Reverse(); // 输出3,2,1

9.DefaultIfEmpty()

当序列为空时,DefaultIfEmpty()为序列添加一个元素,使用元素的默认值,或者指定元素的值,例如:

int[] array = { };
var query = array.DefaultIfEmpty(); // 输出0
var query2 = array.DefaultIfEmpty(100); // 输出100

注意到int是结构类型(值类型),它的默认值为0。 当为类类型时,默认值为null,此时如果不指定默认值则会抛出异常:未将对象引用设置到对象的实例。

ProductCollection col3 = new ProductCollection();
var query = col3.DefaultIfEmpty(); // null
query.ShowConsole();

10.Distinct()
如其名称所表示的,Distinct()运算符用于剔除序列中的重复元素,并返回其余的所有元素。

int[] array = { 1, 2, 2, 3 };
var query = array.Distinct(); // 得到 1,2,3

11.GroupBy() 

在LINQ中,GroupBy()的结果可以是一个树形结构,即序列中的元素也是一个序列。

var query = col.GroupBy(x => x.Category);
            foreach (var item in query)
            {
                Console.WriteLine("<{0}>", item.Key);
                foreach (var p in item)
                {
                    Console.WriteLine(p.ToString());
                }
            }

12.Intersect()Except()

资料

https://www.cnblogs.com/knowledgesea/p/3897665.html

posted @ 2017-02-28 11:41  ~沐风  阅读(369)  评论(0编辑  收藏  举报