扫盲Linq知识
LINQ,语言集成查询(Language Integrated Query),是在.NET Framework 3.5 中出现的技术。
借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据。从技术角度而言,LINQ定义了大约40个查询操作符,如from, select, in, where, group by, orderby, … 使用这些操作符可以编写查询语句。
做软件的,总想代码要怎么样才能更好地复用,要怎么样才更利于扩展,要怎么样更能以不变应万变。就如同微软框架所提供的API一样,在一定程度上避免开发者重复造轮子。拿LINQ来说吧,.NET Framework3.5及之后的版本都已经封装进去,供成千上百万的开发者使用。同一套LINQ语法,它能支持LINQ TO OBJECCT、LINQ TO XML、LINQ TO DATABASE。复用、减少开发工作量及降低学习成本等好处都是不言而喻的。LINQ的学习很像SQL,所以有使用过SQL语句的话,感觉还是蛮熟悉的。
上手简单是学习LINQ的一大好处,语法很像SQL语句的语法。而且学一种技术,可以当多种技术来使用。这是不是很像那种多功能刀,一刀在手,生活无忧。LINQ支持集合、XML、数据库的查询。写代码就像说话,多必失,所以呢,尽量优化自己的代码。这不但有利于减少错误的发生,也有利于提高生产率、降低维护的成本。而使用LINQ也是奔着这个方向发展。
坦白说,我看到网上有很多LINQ方面的教程,知识面介绍都挺好。我只能是厚着脸皮,站在巨人的肩膀上驰骋。本文基本是源于博友08年的文章,感觉他写的很好。虽然抄袭是很可耻的行为,但是回想大学能顺利毕业,论文也是东抄一块,西抄一块。所以现在我是很“蛋定”了。我要响应鲁老爷的拿来主义精神。
LINQ是一种查询语言,所以呢,运用的场景当然也就是查询罗。查哪些,包括LINQ TO OBJECCT、LINQ TO XML、LINQ TO DATABASE。可以说查询的范围很广。每一种都可以出一系列的文章,我们这里主要还是讲 LINQ TO OBJECCT。
来看看从集合中,我们是怎么来查询需要的值。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace LinqApplication
{
class People
{
/// <summary>
/// 名字
/// </summary>
public string FirstName { get; set; }
/// <summary>
/// 姓氏
/// </summary>
public string LastName { get; set; }
/// <summary>
/// 国家
/// </summary>
public string Country { get; set; }
} class Program
{
static void Main(string[] args)
{ List<People> listPeople = new List<People>()
{
new People{FirstName="Peter",LastName="Zhang",Country="China"},
new People{FirstName="Alan",LastName="Guo",Country="Japan"},
new People{FirstName="Linda",LastName="Tang",Country="China"}
};
List<People> result = new List<People>(); foreach (People p in listPeople)
{
if (p.Country == "China")
{
result.Add(p); }
} foreach(People p in result)
{
Console.WriteLine("Your name is :" + p.FirstName + " " + p.LastName);
}
Console.ReadKey();
}
}
}
上面的方法可以说是最直接,最容易想到的方法。上面的实现怎么看也没有觉得有什么好复用的,但是事实是怎么样?就有牛人看出了名堂,善于归纳上面的问题就是判断是跟不是的问题,就想到要去提出来,供以后复用。 当然复用之路也不是一蹴而就的,也是日积月累而成。所以我们也来看看过渡的过程。
/// <summary>
/// 判断是否存在
/// </summary>
/// <param name="p">对象</param>
public static bool IsExist(People p)
{
return p.Country == "China";
}
如果说只是如下方式来实现的话,那还真是白费力气了。
foreach (People p in listPeople)
{
if (IsExist(p))
{
result.Add(p);
}
}
但是结合到委托的话,我们就可以把IsExist(People p)当成一个参数来进行传递。这里我们过渡再快一点,我们把查询的那一段代码提到另一类Helper供以后得用。我们来看看Helper类的代码实现。限于篇幅的问题,只截Helper类的方法。
public class Helper
{
//声明委托
public delegate bool ExistPeople(People p); /// <summary>
/// 获取满足条件的数据
/// </summary>
/// <param name="listPeople">数据集</param>
/// <param name="existPeople">条件</param>
public static List<People> GetPeopleResult(IList<People> listPeople, ExistPeople existPeople)
{
List<People> result = new List<People>();
foreach (People p in listPeople)
{
if (existPeople(p))
{
result.Add(p);
}
}
return result;
}
}
这样我们就可以直接调用,来获取满足条件的数据了。也可以使用C#2.0提供的匿名委托,还可以使用C#3.0的Lambda表述式。代码如下:
static void Main(string[] args)
{
List<People> listPeople = new List<People>()
{
new People{FirstName="Peter",LastName="Zhang",Country="China"},
new People{FirstName="Alan",LastName="Guo",Country="Japan"},
new People{FirstName="Linda",LastName="Tang",Country="China"}
}; IList<People> result = new List<People>(); //直接调用
result = Helper.GetPeopleResult(listPeople, IsExist);
//匿名委托
//result = Helper.GetPeopleResult(listPeople, delegate(People p){ return p.Country == "China" ? true : false;});
//Lambda表达式
//result = Helper.GetPeopleResult(listPeople, people => people.Country == "China"); foreach(People p in result)
{
Console.WriteLine("Your name is :" + p.FirstName + " " + p.LastName);
}
Console.ReadKey();
}
讲到这里,对于具体集合的查询基本上是完成了,但是呢,C#3.0还提供了一种方法,使调用的代码更加直观,那就是扩展方法。通过扩展IList集合的方法,我们就可以通过IList来调用并传递委托条件即可。
Helper类的扩展代码如下:
public static class Helper
{
//声明委托
public delegate bool ExistPeople(People p); /// <summary>
/// 获取满足条件的数据
/// </summary>
/// <param name="listPeople">数据集</param>
/// <param name="existPeople">条件</param>
public static IList<People> GetPeopleResult(this IList<People> listPeople, ExistPeople existPeople)
{
List<People> result = new List<People>();
foreach (People p in listPeople)
{
if (existPeople(p))
{
result.Add(p);
}
}
return result;
}
}
我们看Main方法的调用,是不是很直观了,就像调用集合的方法,并给传递委托条件即可了。Main方法如下:
static void Main(string[] args)
{
List<People> listPeople = new List<People>()
{
new People{FirstName="Peter",LastName="Zhang",Country="China"},
new People{FirstName="Alan",LastName="Guo",Country="Japan"},
new People{FirstName="Linda",LastName="Tang",Country="China"}
}; IList<People> result = new List<People>(); //直接调用
//result = Helper.GetPeopleResult(listPeople, IsExist);
//匿名委托
//result = Helper.GetPeopleResult(listPeople, delegate(People p){ return p.Country == "China";});
//Lambda表达式
//result = Helper.GetPeopleResult(listPeople, people => people.Country == "China");
//扩展方法调用
result = listPeople.GetPeopleResult(people => people.Country == "China"); foreach(People p in result)
{
Console.WriteLine("Your name is :" + p.FirstName + " " + p.LastName);
}
Console.ReadKey();
}
上面是使用GetPeopleResult方法名,但是我们想要的话,是不是就可以实现诸如Select、Where、OrderBy等方法了。基本上方法的介绍就已经完了。但是有一个大的问题,那就是它还比较死,不灵活,因为我们不可能说每个集合里面的对象(本文是People)都重复来写。这里肯定是需要提供一种方式,使它能够接受不同的对象,这样才有利于我们复用。因为IList继承自IEnumerable,所以可以给IEnumerable实现扩展方法,然后利用泛型的特征,就可以给不同的对象来复用,代码如下:
public static class Helper
{
public delegate bool Condtion<T>(T t);
public static IEnumerable<T> GetPeopleResult<T>(this IEnumerable<T> items, Condtion<T> condition)
{
foreach (T t in items)
{
if (condition(t))
{
//C# 2.0里出现的一个关键字,返回一个迭代器
yield return t;
}
}
}
}
Main方法就不贴全部了,毕竟上面都重复好几回,只贴调用那一句:
IEnumerable<People> result = Helper.GetPeopleResult<People>(listPeople, people => people.Country == "China");
而C# 3.0则给我们提供var关键字,被称为推断类型。
var 关键字能指示编译器根据初始化语句右侧的表达式推断变量的类型。推断类型可以是内置类型、匿名类型、用户定义类型、.NET Framework 类库中定义的类型或任何表达式。所以上面的式子可以写成如下方式:
var result = Helper.GetPeopleResult<People>(listPeople, people => people.Country == "China");
到此本文就正式结束,站在前人的肩膀下感觉真好,很多成果就是可以拿来就用,乐哉乐哉!希望大伙一起好好学习,天天向上了。
扫盲Linq知识的更多相关文章
- Linq 知识总结
一.说明: LINQ,语言集成查询(Language INtegrated Query)是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相 ...
- Linq 知识回顾
开篇语 在说LINQ之前必须先说说几个重要的C#语言特性 与LINQ有关的语言特性 隐式类型 (1)源起 在隐式类型出现之前, 我们在声明一个变量的时候, 总是要为一个变量指定他的类型 甚至在fore ...
- Linq知识小结
Linq语法小结:有两种形式的语法可供我们在写Linq查询时使用,分别是“查询语法”.“方法语法”.1)先看个列子,有个直观认识 int[] arr = { 12, 2,45,34,23,18 ...
- Linq知识小总结
一.投影操作符 Select Select操作符对单个序列或集合中的值进行投影. 返回 IEnumerable<类名> //查询语法 var query = from e in db.Em ...
- 前端知识扫盲-VUE知识篇一(VUE核心知识)
最近对整个前端的知识做了一次复盘,总结了一些知识点,分享给大家有助于加深印象. 想要更加理解透彻的同学,还需要大家自己去查阅资料或者翻看源码.后面会陆续的更新一些相关注知识点的文章. 文章只提出问题, ...
- Linq知识大全
select的源码public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable< ...
- TFS二次开发、C#知识点、SQL知识
TFS二次开发.C#知识点.SQL知识总结目录 TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一 ...
- LinqToDB 源码分析——轻谈Linq查询
LinqToDB框架最大的优势应该是实现了对Linq的支持.如果少了这一个功能相信他在使用上的快感会少了一个层次.本来笔者想要直接讲解LinqToDB框架是如何实现对Linq的支持.写到一半的时候却发 ...
- Java进击C#——应用开发之Linq和EF
本章简言 上一章笔者对于WinForm开发过程用到的几个知识点做了讲解.笔者们可以以此为开端进行学习.而本章我们来讲一个跟ORM思想有关的知识点.在讲之前让我们想一下关于JAVA的hibernate知 ...
随机推荐
- Java Concurrency - 浅析 Phaser 的用法
One of the most complex and powerful functionalities offered by the Java concurrency API is the abil ...
- Linux 命令 - umask: 显示或设置文件模式掩码值
umask 命令控制着创建文件时指定给文件的默认权限.它使用八进制表示法从文件模式属性中删除一个位掩码. 参见下面的例子: [huey@huey-K42JE cmdline]$ rm -f foo.t ...
- Messenger实现Android IPC
当Service不需要支持并发操作时Messenger会非常有用.Messenger类使用Handler执行每个传入的消息,所有客户端的调用都按顺序运行在同一个线程上,这和AIDL是有区别的,AIDL ...
- android手机操作SD的使用方法
写入SD卡 package com.example.openfileproject; import java.io.File; import java.io.FileInputStream; impo ...
- DOS批处理命令-SET命令
SET是专门用来创建.设置.查看或删除环境变量. 总结了下,SET的使用语法一般有下面几种 1.SET 变量名=变量值 这边有一点要注意的,就是变量名和变量值中间的等号两端不需要也不能有空格 看看下面 ...
- Hyper-V 虚拟机连接外部网络
Hyper-V创建好虚拟机之后,在默认配置下是没有网络连接的,这个时候就需要进行简单的配置,即可让虚拟机连接外部网络: 在Hyper-V管理器中,右键点击后出现菜单,选择"虚拟交换机管理器& ...
- SAP校园招聘笔试
一直就向往着SAP公司,终于,有幸今天参加了SAP校园招聘的笔试.下面我就来简单说说这个笔试的内容. 笔试分为两大部分,一部分是逻辑题,就是些什么阅读分析计算balabala的一堆,是全英文的.另外一 ...
- 真正的inotify+rsync实时同步 彻底告别同步慢
真正的inotify+rsync实时同步 彻底告别同步慢 http://www.ttlsa.com/web/let-infotify-rsync-fast/ 背景 我们公司在用in ...
- 在Spring中使用cache(EhCache的对象缓存和页面缓存)
Spring框架从version3.1开始支持cache,并在version4.1版本中对cache功能进行了增强. spring cache 的关键原理就是 spring AOP,通过 spring ...
- DTCMS中部分IE8不支持webupload上传附件的控件,更改为ajaxfileupload
dialog\dialog_attach.aspx <!DOCTYPE html> <html> <head> <meta http-equiv=" ...