C# Linq To Objects初探

本文介绍了Linq(Language Integrated Query)的基本概念及其在.NET 3.5中的应用,包括Linq to Objects、Linq to XML及Linq to ADO.NET等内容。通过实例展示了如何使用查询方法和查询语句进行数据筛选、排序等操作。

一、Linq简介(Language Integrated Query)

    不管使用.NET平台创建何种类型的应用程序,都要在运行时访问某种形式的数据,例如,XML文件、内存中的集合、关系数据库等。在过去,根据数据未知的不同,程序要需要使用不同且不相关的API访问数据。Linq.NET3.5所引入的语言集成查询,它为CLR提供了一种简明的、对称的、强类型的方式访问数据存储。Linq提供了很多扩展方法便于集合的排序、组合和计算查询结果的统计数据等操作Linq目前支持对关系型数据、XML以及内存中的数据机构和等多种形式的操作。其语法和SQL很类似,但是其内部机制完全不一样的。


图Linq框架介绍

1、架构介绍

Linq to Objects:提供了对内存中几何数据的实体对象映射(本文的主要内容)

Linq to XML:应用于层次性XML。

Linq to ADO.NET(包含以下三部分)

    a)Linq to Datasets:应用于DataSet
    b)Linq To SQL:应用于SQL Server数据库
    c) Linq to Entities,应用于SQL Server之外的关系型数据库,并提供了其他数据库的扩展接口;

2. C#与Linq相关的特性

(1)隐式类型与本地变量(var关键字---强类型)
源起:在隐式类型出现之前,我们在声明一个变量的时候,总是要为一个变量指定他的类型,甚至在foreach一个集合的时候,也要为遍历的集合的元素,指定变量的类型,隐式类型的出现,程序员就不用再做这个工作了。

eg:

          var a = 1; //int a = 1;
      var b = "123";//string b = "123"; 
      var myObj = new MyObj();//MyObj myObj = new MyObj()

(2)对象/集合初始化语法(初始化器)

(3)Lambda表达式(操作符:=>)它极大的简化了.NET委托的使用。

(4)基本语法:(参数列表)=>方法体

(5)参数列表中的参数类型可以是明确类型或者是推断类型(隐式声明的一个变量)。
如果是推断类型,则参数的数据类型将由编译器根据上下文自动推断出来。

List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
//匿名方法-委托方式            
arr.ForEach(new Action<int>(delegate(int a) { Console.WriteLine(a); }));
//Lambda表达式方式
arr.ForEach(new Action<int>(a => Console.WriteLine(a)));

a是输入参数,编译器可以自动推断出它是什么类型的,如果没有输入参数,可以写成这样:

() => Console.WriteLine("ddd")


Console.WriteLine(a)是要执行的语句。如果是多条语句的话,可以用{}包起来。如果需要返回值的话,可以直接写return语句。
 扩展方法(关键字:this、static):可以(不)是同一程序集。形式如:

Public  static  int  TotalCount(this  ACLASS  a)
{
	//code。。。
}

(6)匿名类型
(7)自动属性

3. Linq的其他说明

操作对象为:任何实现了Ienumerable<>接口的数据集

 LINQ查询表达式是强类型的;C#编译器会保证这些表达式在语法上是合法的。
 在LINQ中,数据源和查询结果实际上都是IEnumerable<T>或IQueryable<T>类型对象,所以可以通过使用普通对象的形式(调用方法、使用属性等)对数据源进行查询或使用查询结果数据。

4. Linq操作符


    IEnumerable提供的方法包括数值运算(Sum、Min、Max、Average)、元素数量(Count、LongCount)、取值(First、Last、ElementAt等)、提取子集(Skip、SkipWhile、Take、TakeWhile、)集合操作(Reverse、Concat、Distinct、Except、Intersect、Union(效率很差 )、SequenceEqual等)、投影操作符(Select、SelectMany—返回一个序列)--将序列中的元素投影到新的表中、排序操作符(OrderBy、ThenBy、OrderByDesding等)、转换操作符(.ToList()、.ToArray()、.ToDictionary()),这些方法提供了Linq所需要的所有操作。
图2列出了Linq几个常用的操作符,其余的大家可以自己了解一下。


图2 Linq常用操作符

二、 实战:Linq To Objects(其他方面暂不涉及)

1、查询步骤

一般情况下,一次查询实际经过以下三步,如图3所示:


图3 查询步骤

1、举例类

public class People
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
}

2、查询方法方式

peoples.Where(it => it.Name == "张三").OrderBy(it => it.Age).ToList().ForEach(
                it =>
                {
                    Console.WriteLine(it.Name);
                });


3、查询语句方式 

 var ps =     from p
                       in peoples
                       where p.Name == "sh" && p.Age >= 12 || p.Address == "上海"
                       select p;


Linq简要的操作(查询方法方式):

(1)初识操作符:=>
(2)投影操作符:select、selectMany
(3)数值运算操作符:Sum、Min、Max、Average
(4)取值:First、Last、ElementAt
(5)排序:Orderby
(6)集合操作:Reverse、Distinct、Except、Intersect、Union(效率很差)
(7)转换操作符ToList()、ToArray()、ToDictionary()
(8)分组:Group() ---(解释中间元组的概念iGrouping)

三、 常见的坑

(1)Foreach()循环时要考虑线程安全性

(2)foreach时不要试图对被遍历的集合进行remove和add等操作。
任何集合,即使被标记为线程安全的,在foreach的时候,增加项和移除项的操作都会导致异常。

(3)IEnumerable接口是Linq特性的核心接口
只有实现了IEnumerable接口的集合才能执行相关的Linq操作,比如select,where等这些操作。

(4) 关于匿名类型,不要任性命名,需有区分度
匿名类型用着很舒服,但是为了不致于混淆,建议清晰明白的进行变量命名;

(5)注意数据集合的边界判断(是否为null和是否有数据)
当对一个数据集合进行Linq处理的时候,首先确保该数据非空,并且有数据成员。
First()等。

四、 其他事项

1、 单步调试中间过程比较困难;F11。
2、代码的编写集成度略高,需要很谨慎。
3、参考:https://msdn.microsoft.com/zh-cn/library/bb384065.aspx









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值