注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

LINQ入门(一)  

2012-01-04 15:31:05|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

LINQLanguage Integrated Query,语言集成查询,是C#3.0中新增加的扩展,用于非常大的数据集合。

VS2008中有3个内置的LINQ变体:LINQ to ObjectLINQ to SQLLINQ to XML,并且还有为其他数据源提供扩展的LINQ Provider

简单查询

需要添加命名空间的引用:using System.Linq;

static void Main(string[] args)

{

    string[] names = new string[] { "Aspartame", "Banana", "CSharp", "Google", "Language", "Gauss", "Shell", "Pascal" };

    var result = from n in names

                 where n.EndsWith("e")

                 select n;

    foreach (var v in result)

        Console.WriteLine(v);

    Console.Read();

}

该程序用于查询names中以e为结尾的元素,运行结果是:

Aspartame

Google

Language

这种查询很类似SQL语句,var声明一个变量为一般变量类型,让编译器自己去推断类型,from之句指定了数据源,n是数据源中数据的一个代表。where子句指定了查询的条件,有时候可以不需要,最后的select子句指定了集合中包含了那些元素,这个是必须的。

查询语法和方法语法

前面介绍的一个简单查询就是查询语法,由于理解方便,这种语法是在LINQ中编写查询的首选方法,但是LINQ实现为一系列的扩展方法,于是就有了方法语法(也叫做显式语法)这话总方式,两者的效果是一样的。

例如,前面的查询语句可以修改为:

var result = names.Where(n => n.EndsWith("e"));

这就是方法语法了,方法语法中“n => n.EndsWith("e")”被称为λ表达式,其中=>运算符称为λ运算符,可以读作goes to 或者such that。这种表达式创建一个匿名的方法(函数),λ表达式是创建函数的缩写方法,对于上例where中的表达式,n就是参数,函数返回true的条件就是参数ne结尾,你会在以后使用方法语法的时候大量使用λ表达式。

Reflector中查看编译后的程序,会得到两个带有[CompilerGenerated]属性的方法,这两个方法都是编译器生成的,并非开发人员编写:

private static bool <Main>b__0(string n)

{

    return n.EndsWith("e");

}

private static Func<string, bool> CS$<>9__CachedAnonymousMethodDelegate1;

第一个是方法,第二个是该方法的代理,这就是这些方法被称为匿名方法的原因。

查询结果排序

可以使用orderby语句执行排序,不过查询语法和方法语法中的顺序有所不同。

查询方法:

var result = from n in names

             where n.EndsWith("e")

             orderby n

             select n;

方法语法:

var result = names.OrderBy(n=>n).Where(n => n.EndsWith("e"));

这会按照字母顺序进行排序,如果有必要倒序排序的话,就要使用descending了,分别如下:

var result = from n in names

             where n.EndsWith("e")

             orderby n descending

             select n;

var result = names.OrderByDescending(n=>n).Where(n => n.EndsWith("e"));

注意方法语法中的orderby方法是在where方法前面的,而查询语法中orderby子句是在where子句后面的。

大型数据的查询

事实上前面的LINQ查询只能作为示例,体现不了LINQ的优势,LINQ的优势体现在大量的数据集中,例如下例:

static void Main(string[] args)

{

    int[] Huge = GenerateNumber(1000000);

    var result = Huge.OrderBy(n => n).Where(n => n < 20000 && n > 10000);

    foreach (var v in result)

        Console.WriteLine(v);

    Console.Read();

}

private static int[] GenerateNumber(int n)

{

    int[] ret = new int[n];

    Random r = new Random(DateTime.Now.Millisecond);

    for (int i = 0; i < n; i++)

        ret[i] = r.Next();

    return ret;

}

该程序生成了一个巨大的随机数组,并显示介于1000020000之间的数,LINQ查询有速度优势吗?为了对比运行结果,可以使用如下测试代码:

static void Main(string[] args)

{

    int[] Huge = GenerateNumber(1000000);

    Stopwatch watcher = new Stopwatch();

   

    Console.WriteLine("Using LOOP:");

   

    watcher.Start();

    foreach (int i in Huge)

    {

        if (i > 10000 && i < 20000)

            Console.WriteLine(i);

    }

    watcher.Stop();

    Console.WriteLine("Elapsed Time" + watcher.ElapsedMilliseconds + " Milliseconds");

    watcher.Reset();

    Console.WriteLine("Using LINQ:");          

    watcher.Start();

    var result = Huge.Where(n => n < 20000 && n > 10000);

    foreach (var v in result)

        Console.WriteLine(v);

    watcher.Stop();

    Console.WriteLine("Elapsed Time" + watcher.ElapsedMilliseconds + " Milliseconds");

    Console.Read();

}

某次运行结果为:

Using LOOP:

15521

Elapsed Time8 Milliseconds

Using LINQ:

15521

Elapsed Time12 Milliseconds

可见LINQ查询还是稍慢了一点,另外,如果在LINQ查询中使用排序的话,会给性能带来显著的影响(对于本例性能下降了两个数量级)可见LINQ查询性能还是会比直接查询低一点,不过如果考虑到简单循环查询中结果的存放问题,或许LINQ的查询结果应该能和简单查询的性能旗鼓相当,虽然性能略差,但是带来的好处确实很显著的。

统计运算符

LINQ查询支持统计运算符,其实和SQL中的聚集函数类似,这些运算符包含CountMinMaxAverageSum,看下例:

static void Main(string[] args)

{

    int[] Huge = GenerateNumber(1000000);

    var result = Huge.Where(n => n > 1000);

    Console.Write("Average of Numbers larger than 1000:");

    Console.WriteLine(result.Average());

    Console.Write("Max of Numbers larger than 1000");

    Console.WriteLine(result.Max());

    Console.Write("Min of Numbers larger than 1000:");

    Console.WriteLine(result.Min());

    Console.Write("Count of Numbers larger than 1000:");

    Console.WriteLine(result.Count());

    Console.Write("Sum of Numbers larger than 1000:");

    Console.WriteLine(result.Sum(n=>(long)n));

    Console.Read();

}

运行结果为:

Average of Numbers larger than 1000:1073930167.11988

Max of Numbers larger than 10002147481579

Min of Numbers larger than 1000:3805

Count of Numbers larger than 1000:1000000

Sum of Numbers larger than 1000:1073930167119878

注意这个例子里面的Sum运算符,由于简单的相加会溢出,所以给Sum运算符传递了一个λ表达式,将其参数转换为long类型,这个例子还表明,统计运算符也是可以接收λ表达式的。

  评论这张
 
阅读(1013)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016