第二十章 数据访问(In .net4.5) 之 使用LINQ

1. 概述

  .net3.5中新添加给C#的LINQ查询,提供了直观便捷的数据查询方式。并且支持多种数据源的查询。

  本章介绍标准的LINQ操作,如何用最优的方式使用LINQ 以及 LINQ to XML.

2. 主要内容

  2.1 使LINQ可行的语言特性

    ① 隐式类型(Implicitly typed variables): 使用var标记,由编译器推断类型。也是强命名的。

    ② 对象初始化语法(Object initialization syntax):用一种简洁的语法进行对象初始化。

var people = new List<Person> 
{ 
    new Person 
    { 
        FirstName = “John”, 
        LastName = “Doe” 
    },   
    new Person 
    { 
        FirstName = “Jane”, 
        LastName = “Doe” 
    } 
};

    ③ Lambda表达式:是匿名方法的简化形式。使用 => 符号。

Func<intint> myDelegate = 
    delegate(int x) 
    { 
        return x * 2; 
    }; 
Console.WriteLine(myDelegate(21)); // Displays 42

//用Lambda表达式改写
Func<intint> myDelegate = x => x * 2; 
Console.WriteLine(myDelegate(21)); // Displays 42

    ④ 扩展方法

      扩展方法可以在不继承某类型的情况下给其添加新的行为。扩展方法必须定义在静态类中,用this标记第一个参数。

public static class IntExtensions 
{ 
    public static int Multiply(this int x, int y) 
    { 
        return x * y; 
    } 
} 
 
int x = 2; 
Console.WriteLine(x.Multiply(3)); // Displays 6

    ⑤ 匿名类:同时使用 对象初始化标记 和 隐式类型。

var person = new 
{ 
    FirstName = “John”, 
    LastName = “Doe” 
}; 
 
Console.WriteLine(person.GetType().Name); // Displays “<>f__AnonymousType0`2”

  2.2 使用LINQ查询

int[] data = { 125811 }; 
 
var result = from d in data 
             where d % 2 == 0 
             select d; 
 
foreach (int i in result) 
{ 
    Console.WriteLine(i); 
}  
// Displays 2 8  

    上述查询式语法可以被改写为方法式语法

var result = data.Where(d => d % 2 == 0);

    *where方法就是 IEnumerable<T>上的扩展方法。

    ① 标准LINQ操作包括: All, Any, Average, Cast, Count, Distinct, GroupBy, Join, Max, Min, OrderBy, OrderByDescending,

      Select, SelectMany, Skip, SkipWhile, Sum, Take, TakeWhile, ThenBy, ThenByDescending, and Where.

int[] data = { 125811 }; 
var result = from d in data 
             where d > 5 
             orderby d descending 
             select d; 
Console.WriteLine(string.Join(“, “, result)); // Displays 11, 8

    * 可以将多个数据源的数据合并操作

int[] data1 = { 125 }; 
int[] data2 = { 246}; 
 
var result = from d1 in data1 
             from d2 in data2 
             select d1 * d2; 
 
Console.WriteLine(string.Join(“, “, result)); // Displays 2, 4, 6, 4, 8, 12, 10, 20, 30

    projection 和 grouping

var result = from o in orders 
             from l in o.OrderLines 
             group l by l.Product into p 
             select new 
                 { 
                    Product = p.Key, 
                    Amount = p.Sum(x => x.Amount) 
                 };

    使用Skip和Take实现分页

var pagedOrders = orders 
                .Skip((pageIndex 1) * pageSize) 
                .Take(pageSize);

  2.3 LINQ如何工作

    实现自己的where方法

public static class LinqExtensions 
{ 
    public static IEnumerable<TSource> Where<TSource>( 
        this IEnumerable<TSource> source, 
        Func<TSource, bool> predicate) 
    { 
        foreach (TSource item in source) 
        { 
            if (predicate(item)) 
            { 
                yield return item; 
            } 
        } 
    } 
}

  2.4 LINQ to Xml

    ① 查询

XDocument doc = XDocument.Parse(xml); 
IEnumerable<string> personNames = from p in doc.Descendants(“Person”) 
                                  where p.Descendants(“PhoneNumber”).Any() 
                                  let name = (string)p.Attribute(“firstName”)  
                                              + “ “ + (string)p.Attribute(“lastName”) 
                                  orderby name 
                                  select name;

    ② 创建

XElement root = new XElement(“Root”, 
            new List<XElement> 
            { 
                new XElement(“Child1”), 
                new XElement(“Child2”), 
                new XElement(“Child3”) 
            }, 
            new XAttribute(“MyAttribute”, 42)); 
root.Save(“test.xml”); 
 
//Outputs: 
//<Root MyAttribute=”42”> 
//    <Child1 />  
//    <Child2 />  
//    <Child3 />  
//</Root>

    ③ 修改

XElement root = XElement.Parse(xml); 
 
XElement newTree new XElement(“People”, 
    from p in root.Descendants(“Person”) 
    let name = (string)p.Attribute(“firstName”) + (string)p.Attribute(“lastName”) 
    let contactDetails = p.Element(“ContactDetails”) 
    select new XElement(“Person”, 
        new XAttribute(“IsMale”, name.Contains(“John”)), 
        p.Attributes(), 
        new XElement(“ContactDetails”, 
            contactDetails.Element(“EmailAddress”), 
            contactDetails.Element(“PhoneNumber”)  
                ?? new XElement(“PhoneNumber”, “112233455”) 
        )));

3. 总结

  ① LINQ, 以一种统一的语法面向多种数据源编写查询语句。

  ② LINQ用到的一些语言特性包括:implicit typing, object initialization syntax, lambdas, extension methods, and anonymous types。

  ③ 可以使用查询式语法或者方法式语法来编写LINQ查询。

  ④ LINQ是延迟执行模式,声明的时候是不会实际执行查询的,第一次遍历开始时才会执行。调用ToList或者Count方法时会立即执行。

  ⑤ 可以使用LINQ to Xml 来查询、创建 和 修改 xml 数据。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。