zoukankan      html  css  js  c++  java
  • LINQ(语言集成查询)

     

    LINQ,语言集成查询(Language Integrated Query)是一组用于c#Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。
    中文名
    语言集成查询
    外文名
    Language Integrated Query
    开发公司
    微软
    语    言
    C#,Visual Basic

    基本含义

    编辑
    从技术角度而言,LINQ定义了大约40个查询操作符,如select、from、in、where以及order by(C#中)。使用这些操作符可以编写查询语句。不过,这些查询还可以基于很多类型的数据,每个数据类型都需要一个单独的LINQ类型。
    经过了最近 20 年,面向对象编程技术( object-oriented (OO) programming technologies )在工业领域的应用已经进入了一个稳定的发展阶段。程序员现在都已经认同像 类(classes)、对象(objects)、方法(methods)这样的语言特性。考察现在和下一代的技术,一个新的编程技术的重大挑战开始呈现出来,即面向对象技术诞生以来并没有解决降低访问和整合信息数据( accessing and integrating information )的复杂度的问题。其中两个最主要访问的数据源与数据库(database)和XML标准通用标记语言下的一个应用)相关。
    LINQ 提供了一条更常规的途径即给.Net Framework添加一些可以应用于所有信息源( all sources of information )的具有多种用途( general-purpose )的语法查询特性( query facilities ),这是比向开发语言和运行时( runtime )添加一些关系数据( relational )特性或者类似 XML 特性( XML-specific )更好的方式。这些语法特性就叫做 .NET Language Integrated Query (LINQ) 。
    包含 DLinq 和 XLinq。

    相关概念

    编辑
    1. LINQ的读法:(1)lin k (2)lin q
    2. LINQ的全称:Language-Integrated Query
    3. LINQ的关键词:from, select, in, where, group by, orderby, …
    4. LINQ的写法:
    1) from 临时变量 in 实现IEnumerable<T>接口的对象
    [orderby 条件]
    [group by 条件]
    select 临时变量中被查询的值
    2) 实现IEnumerable<T>接口的对象.LINQ方法名(lambda表达式)。如:
    string input = "hello world";
    int count = input.Count(w=>w == 'o'); //查询字母o出现的次数
    注意:能够使用LINQ的对象需要实现IEnumerable<T>接口。并且LINQ的查询表达式是在最近一次创建对 象时才被编译的。
    5. 命名空间(.NET Framework):System.Linq;
    注意:Linq是在.NET Framework 3.5 中出现的技术,所以在创建新项目的时候必须要选3.5或者更高版 本,否则无法使用。选择3.5或更高版本的.NET Framework之后,创建类文件中会自动包含System.Linq 的命名空间。

    语法实例

    编辑
    C#3.0 LINQ 查询语法
    首先来看一个很简单的LINQ查询例子,查询一个int数组中小于5的数字,并按照大小顺序排列:
    static void Main(string[] args)
    {
    int[] arr = new int[] { 8, 5, 89, 41, 1, 2, 3, 65, 1 };
    var m = from n in arr where n < 5 orderby n descending select n;//小于5,并且倒叙排列显示
    foreach (var n in m)
    {
    Console.WriteLine(n);
    }
    Console.ReadLine();
    }
    上述代码除了LINQ查询语法外,其他都是我们所熟悉的语法,而LINQ查询语法跟SQL查询语法很相似,除了先后顺序。
    Q:为何 LINQ 查询语法是以 from 关键字开头的,而不是以 select 关键字开头的?select 开头这种写法跟SQL的写法更接近,更易懂呀?
    A:简单来说,为了IDE的智能感知(Intellisence)这个功能,select 关键字放在后面了。
    编程语言以 select 开头写LINQ查询语法不是没出现过,你如果使用过2005年的VB9 CTP 版本,那时候VB9的LINQ查询语法就是 select 关键字在前面,但是 select 关键字在前面,在做智能感知(Intelisence)时候就很头大。经过微软IDE组的权衡,确定了把 from 关键字放在最前面。
    那时候 VB9 LINQ的查询语法还是 select 参数在最前面。不过后来 VB9 测试版改成了跟 C# 一样的做法, from 关键字放在最前面了。
    更详细的解释,来自装配脑袋
    假设你要书写这样的代码:Select p. Name, p.Age From p In persons Where xxx ,代码是一个个字符输入的。
    我们在写到 p in persons 之前,p 的类型是无法推测的,所以写 Select p. 的时候,Name之类的属性不会弹出智能提示来。
    这样就需要先去写 From 这句,再回来写 Select。
    微软IDE组经过反复考虑决定,还不如就把 Select 写到后面了。于是编程语言中的写法就确定这样来写了。
    VB9 的这个变化可以参看这篇博客:
    Select/From vs. From/Select revisited...
    我们再来看一个稍稍复杂的LINQ查询:
    在我们列举的语言字符串中,我们希望按照字符长短,分类列举出来,实现代码如下:
    static void Main(string[] args)
    {
    string[] languages = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++Builder", "Kylix", "Perl", "Python" };
    var query = from item in languages
    group item by item.Length into lengthGroups
    orderby lengthGroups.Key
    select lengthGroups;
    foreach (var item in query)
    {
    Console.WriteLine("strings of length{0}", item.Key);
    foreach (var val in item)
    {
    Console.WriteLine(val);
    }
    }
    Console.ReadLine();
    }
    其中的 into 关键字表示 将前一个查询的结果视为后续查询的生成器,这里是跟 group by 一起使用的。
    LINQ中的Group by不要跟 SQL 中的Group by 混淆,SQL由于是二维结构,Group by 的一些逻辑受二维结构的约束,无法像 LINQ 中的Group by 这么灵活。
    事实上,LINQ的查询语法存在以下两种形式:
    查询方法方式:(Methord Syntax)
    主要利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式进行查询
    查询语句方式:(Query Syntax)一种更接近SQL语法的查询方式,可读性更好。

    原理浅析

    编辑
    LINQ(Language Integrated Query)是Visual Studio 2008中的领军人物。借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据。目前为止LINQ所支持的数据源SQL ServerOracleXML标准通用标记语言下的一个应用)以及内存中的数据集合。开发人员也可以使用其提供的扩展框架添加更多的数据源,例如MySQL、Amazon甚至是GoogleDesktop。
    一般来讲,这类查询语句的一个重要特点就是可以并行化执行。虽然有些情况下并行可能会带来一些问题,但这种情况非常少见。这样也就水到渠成地引出了PLINQ这个并行处理的LINQ类库。
    PLINQ原名为Parallel LINQ,支持XML和内存中的数据集合。执行于远程服务器上的查询语句(例如LINQ to SQL)显然无法实现这个功能。
    将LINQ语句转换为PLINQ语句极为简单——只需要在查询语句中From子句所指定的数据源的最后添加.AsParallel()即可。随后Where、OrderBy和Select子句将自动改为调用这个并行的LINQ版本。
    据MSDN Magazine介绍,PLINQ可以以三种方式执行。第一种是管道处理:一个线程用来读取数据源,而其他的线程则用来处理查询语句,二者同步进行——虽然这个单一的消费线程可能并不那么容易与多个生产线程同步。不过若是能够仔细配置好负载平衡的话,仍然会极大地减少内存占用。
    第二种模式叫做“stop and go”,用于处理结果集需要被一次返回时(例如调用ToList、ToArray或对结果排序)的情况。在这种模式下,将依次完成各个处理过程,并将结果统一返回给消费线程。这个模式在性能上将优于第一种模式,因为它省去了用来保持线程同步所花费的开销。
    最后一种方法叫做“inverted enumeration”。该方法并不需要实现收集到所有的输出,然后在单一的线程中处理,而是将最终调用的函数通过ForAll扩展传递到每个线程中。这是目前为止最快的一种处理模式,不过这需要传递到ForAll中的函数是线程安全的,且最好不包含任何lock之类的互斥语句。
    若是PLINQ中任意的一个线程抛出异常,那么所有的其他线程将会被终止。若是抛出了多个异常,那么这些异常将被组合成一个MultipleFailuresException类型的异常,但每个异常的调用堆栈仍会被保留。

    使用优点

    编辑
    1、无需复杂学习过程即可上手
    2、编写更少代码即可创建完整应用。
    3、更快开发错误更少的应用程序。
    4、无需求助奇怪的编程技巧就可合并数据源
    5、能够大幅减少过程控制语句的代码块,使代码的可读性和可维护性大幅提高。
    6、任何对象或数据源都可以定制实现Linq适配器,为数据交互带来真正方便。

    函数支持

    编辑
    支持以下公共语言运行时 (CLR) 方法和属性,因为它们可以在查询表达式中进行转换以包含在OData服务的请求 URI 中:
    String成员支持的 OData 函数
    Concat
    string concat(string p0, string p1)
    Contains
    bool substringof(string p0, string p1)
    EndsWith
    bool endswith(string p0, string p1)
    IndexOf
    int indexof(string p0, string p1)
    Length
    int length(string p0)
    Replace
    string replace(string p0, string find, string replace)
    Substring
    string substring(string p0, int pos)
    Substring
    string substring(string p0, int pos, int length)
    ToLower
    string tolower(string p0)
    ToUpper
    string toupper(string p0)
    Trim
    string trim(string p0)
    DateTime成员1支持的 OData 函数
    Day
    int day(DateTime p0)
    Hour
    int hour(DateTime p0)
    Minute
    int minute(DateTime p0)
    Month
    int month(DateTime p0)
    Second
    int second(DateTime p0)
    Year
    int year(DateTime p0)
    1也支持Visual Basic中等效的Microsoft.VisualBasic.DateAndTime的日期和时间属性以及DatePart方法。
    Math成员支持的 OData 函数
    Ceiling
    decimal ceiling(decimal p0)
    Ceiling
    double ceiling(double p0)
    Floor
    decimal floor(decimal p0)
    Floor
    double floor(double p0)
    Round
    decimal round(decimal p0)
    Round
    double round(double p0)
    Expression成员支持的 OData 函数
    TypeIs
    bool isof(type p0)
    客户端或许还可以在客户端上计算其他 CLR 函数。对于无法在客户端上计算以及无法转换为有效请求URI以便在服务器上计算的任何表达式,将引发NotSupportedException。
  • 相关阅读:
    slf4j中的MDC
    redis incr incrby decr decrby命令
    Java接口响应超时监控
    JDK1.7.0_45源码阅读<java.lang.Boolean>
    Debug JDK变量显形
    Java全角、半角字符的关系以及转换
    模型选择
    经验风险最小化
    支持向量机(下)
    支持向量机(上)
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/5481959.html
Copyright © 2011-2022 走看看