新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇

作为一个业余开发,断断续续学.net/c#也有不少日子了,

学习过程中,不断忘了学,学了忘,这让我很苦恼。

以前学习过程中,我总是在笔记本中记录下来知识要点,这么久下来,笔记本都写了四五本了。

然而,随着笔记本的增多,自己很快发现,笔记写了跟没写一样:笔记多了就找不到了……

所以,我觉得还是上博客园写博客,记录自己每天的学习心得。

如果有什么错误的地方,欢迎大神指教,小弟在这给大神跪谢了

============================================================

Linq入门篇

前篇:

    一直以来我都没接触过EF,因为我觉得它涉及到linq等乱七八糟的东西,还不如用原生ado.net舒服。最近想开了,大胆得尝试EF,那么就向着原先最头疼的linq攻关。

  我想很多人肯定跟我一样,第一次接触linq的时候,被linq,特别是它那些什么where 、order by子句弄得一脸懵逼。 我向来喜欢刨根寻底,对于那些只知其然不知其所以然的东西,我总是觉得浑身不舒服,这也是阻碍我学习linq的最大障碍。

  问题在于:这个语法到底是怎么回事?这些子句到底有什么联系?

解释:

    linq,书面解释就是Language Integrated Query,语言集成查询。单从字面上和百度百科上的解释,对于我等新手来说,看了恐怕只会更加懵逼,我想写这些的人他们是站在他们已经懂了的立场上写的解释,而不是我们这些不懂的人的立场。

    

   (一)从新手角度来说,要弄懂linq,首先就从以前如何查询集合入手。        关键词:委托    ------------------------如果不知道委托是啥,很简单的一句话可以理解委托:它就是一个存方法的类型。你可以借助委托把方法当做变量传递。

      我们假定有这样一个person类和 person类型 标识符为“persons”的泛型集合。 

  

public  class Person
{
    public string Age{get;set;}
    public string Name{get;set;}
    public string Add{get;set;}
}

public class Program
{
    public void Main()
    {
          List<Person> persons=new List<Person>();
          persons.Add(new Person(){Age=10,Name="张三",Add="成都"});
          persons.Add(new Person(){Age=13,Name="李四",Add="成都"});
          persons.Add(new Person(){Age=17,Name="王五",Add="重庆"});
          persons.Add(new Person(){Age=15,Name="路人",Add="香港"});
    }  
}    

      这样一个list泛型集合中,我们要查询这个集合里面,所有对象的ADD属性为“成都”的对象。传统的查询办法之一就是调用 persons.FindAll(委托参数) 方法。

    public void Main()
    {
          List<Person> persons=new List<Person>();
          persons.Add(new Person(){Age=10,Name="张三",Add="成都"});
          persons.Add(new Person(){Age=13,Name="李四",Add="成都"});
          persons.Add(new Person(){Age=17,Name="王五",Add="重庆"});
          persons.Add(new Person(){Age=15,Name="路人",Add="香港"});

/*chengduPerson是所有Add为成都的集合,找出persons集合中所有地址为成都的Person*/
 List<Person>  chengduPerson=persons.FindAll(p=>p.Add="成都");

    }        

      我们用反编译工具点开FindAll()方法看看他们到底是怎么回事呢?

//List<>集合的FindAll的源码

[__DynamicallyInvokable]
        public List<T> FindAll(Predicate<T> match)     //参数是一个泛型委托   这个委托要求方法传递一个集合元素类型的参数,返回一个BOOL值。具体说明在下面
        {
            if (match == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
            }
            List<T> list = new List<T>();
            for (int i = 0; i < this._size; i++)
            {
                if (match(this._items[i]))   //借助match 来判断,传递过来的集合元素是否匹配,如果匹配就加入新的集合中。
                {
                    list.Add(this._items[i]);
                }
            }
            return list;
        }

//参数 Predicate<T> match 的委托声明如下
namespace System
{
    // 摘要:
    //     表示定义一组条件并确定指定对象是否符合这些条件的方法。
    //
    // 参数:
    //   obj:
    //     要按照由此委托表示的方法中定义的条件进行比较的对象。
    //
    // 类型参数:
    //   T:
    //     要比较的对象的类型。
    //
    // 返回结果:
    //     如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。
    public delegate bool Predicate<in T>(T obj);
}

        原来list集合就是借助委托来实现查询对象的。

  

   (二)list集合只是.net中众多集合中的一种,List<>我们可以用FindAll,那其他集合呢?我们可不可以有什么办法让他们都能用一个通用的方法呢?  有! 关键词:扩展方法  IEnumerable<>

              (1) 扩展方法是.net3.0的特性  它的具体语法就是在某个静态类的一个静态方法中第一个参数添加一个(this T name) T是期望添加到的类型。

public static class Test
{
      public static void NewFunc(this string s)
    {………}
}

//将NewFunc添加到字符串对象中,字符串都可以调这个方法。扩展放方法其实并不是真正的给类型加方法,还是有区别的

      (2)IEnumerable<>接口是实现遍历的接口,基本上如list<>、 Dictionary<>等泛型集合都实现了这个接口,与之对应的,非泛型版的集合则实现的是IEnumerable接口

        明白这两点,我们就理解得出一个办法,我们要实现这样一个通用的集合查询。我们要实现使所有集合都可以通用一个方法进行查询,我们可以单独定义一个静态类,给IEnumerable、IEnumerable<>加扩展方法。使所有实现了          IEnumerable、IEnumerable<>的对象都可以调用这两个方法。

 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
}

      借助扩展方法和扩展方法  IEnumerable接口就可以实现所有集合都能调取查询方法。

    (三)重点来了----Linq    关键词 Enumerable 静态类。

      事实上,微软就是这样做的,在namespace System.Linq命名空间下,有一个叫Enumerable的静态类,它定义了WHERE、SELECT、OrderBy等方法,他们都是扩展方法,全部扩展给IEnumerable;

        [__DynamicallyInvokable]
        public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
        {
            if (source == null)
            {
                throw Error.ArgumentNull("source");
            }
            if (selector == null)
            {
                throw Error.ArgumentNull("selector");
            }
            return SelectIterator<TSource, TResult>(source, selector);
        }

        private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
        {
            int iteratorVariable0 = -1;
            foreach (TSource iteratorVariable1 in source)
            {
                iteratorVariable0++;
                yield return selector(iteratorVariable1, iteratorVariable0);
            }
        }
/*Enumerable 类中SELECT方法的源码*/       需要注意,这里有个yield关键字,它的存在,使得这个查询会推迟到集合被遍历的时候才会执行

      微软定义这样一个类,给我们提供了一个巨大的便利,这其实就是Linq的最核心的东西。 而诸如一些简写的子句 例如 from XXX in XXX where XXX.XXX>XXX select XXX  这些WHERE、SELECT子句,实际上就是对这些方法的映射               的语法糖。

      如此一来,我们对Linq就有了一个最基本的了解。通过查看元数据,我们就可以知道我们可以对集合进行怎样的操作。为日后更深入的学习和应用打下良好的基础。

结语:

    实现Linq,用到了委托、多态、扩展方法等C#和面向对象的特性。通过对Linq的学习,再次让我感受到了设计之美。真是受益匪浅。

参考:C#高级编程第11章 Linq

时间: 2024-10-05 01:19:46

新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇的相关文章

2017年2月28日-----------乱码新手自学.net 之特性与验证

现在看asp.net MVC5自学已经到了第六章:数据注解与验证. 话得从以前看MVC music store(音乐商店项目)的源码说起, 最初看music store源码完全就是一脸懵逼,整个程序,找了半天,只看到控制器有少许逻辑代码,例如编辑专辑的视图里面,用户输入的title到底符不符合规范, VIEW里面即无相关验证的JS代码,又没有进行后台的数据判断. 1 @using (Html.BeginForm()) { 2 @Html.ValidationSummary(true) 3 <fi

陈松松:新注册视频平台帐号,养号30天执行方法

每个视频,都是你的金牌业务员 这是我写的第18篇视频营销原创文章 与其搜索十年,不如花一年的时间学习,去赚9年的高薪! 规则更新块,视频流量越来越精准 现在视频平台规则更新越来越块! 原来大家都可以批量帐号操作视频营销,现在很难行得通了. 想要上传视频,必须验证手机号,而且现在手机号必须实名,并且每个人最多是5个手机号,想要批量操作,难度比以前大的太多了,可想,在其他细节方面,那就更严格了. 所以,现在操作视频营销就不能以前那种吊儿郎当的心态去操作,必须根据视频平台现有规则,用最好的方法,你才能

MYSQL新手入门篇

MYSQL新手入门篇 一.数据库的简介 什么是数据库? 数据的仓库,如:在atm的实例中我们创建一个db目录称之为数据库 什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 他们是数据库软件,主要功能为两部分:1.讲数据保存到内存或者文件.2.接受特定的命令对数据进行操作 什么是SQL? 上述问题说过,数据库要接受特定的命令,这个命令就是用SQL编写,他是结构化查询语言(Structured Query Language)的缩写,一种专门与数据库交互的

Pycharm新手教程,只需要看这篇就够了

pycharm是一款高效的python IDE工具,它非常强大,且可以跨平台,是新手首选工具!下面我给第一次使用这款软件的朋友做一个简单的使用教程,希望能给你带来帮助! 目前pycharm一共有两个版本,Professional(专业版本)」和「社区版」,专业版功能最强大,主要是为 Python 和 web 开发者而准备,是需要付费的.社区版是专业版的阉割版,比较轻量级,主要是为 Python 和数据专家而准备的.一般我们做开发,下载专业版本比较合适. 文章转自:django中文网---Pych

普通抖音新手如何从0开始入门3个月做到粉丝10w+

普通抖音新手如何从0开始入门3个月做到粉丝100w+ 今年以来,明显感觉抖音很火,大有干掉微信,取代淘宝,京东的感觉,如今年轻人,一周7天有7天要玩抖音,所以说未来不可估量. 如是,2019春节以后,来深圳的第一件事就是一有空我就研究抖音,经过我3个月的学习,摸索,研究,在下面这些方面形成了比较完整的抖音研究报告, 如今,我也自己新建了抖音号:du0755 ,按照我的研究报告来运营,发布作品,大家可以关注,看看效果,3个月能否做到粉丝10w+ 抖音研究报告:包含这些方面的内容 01.如今,有人说

【经验分享】新手学Java编程语言怎么入门?

新手学Java编程语言怎么入门?掌握语言基础是第一步,了解java基础知识,Java关键字.核心概念或者基本编码技术.掌握操作符.控制执行流程.访问权限控制.复用类.多态.接口.字符串.泛型.数组.容器深入研究.JavaI/O系统.枚举类型.并发以及图形化用户界面等内容. 为了帮助大家更轻松的学好java开发,给大家分享一套java开发学习资料,小编推荐一个学java开发技术的学习裙:三七四三二零二八二,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有开发工具,很多干

新手Oracle安装及使用入门

新手Oracle安装及使用入门 一.安装Oracle Step1 下载oracle压缩包并解压到同一文件夹下面 Step2 双击setup.exe进行安装 Step3:进入如下界面配置: 邮箱可不填,去掉更新 除了设置密码,其他均可默认安装! 可自行选择安装路径,确保该安装盘有4G以上内存可使用就行. 若检测有问题就选择“全部忽略” 完成之后接着进行数据库创建(wait for long~~): 可按照以上在浏览器输入该url进行登录并管理服务端,登录成功见如下界面(此步骤也可以跳过不操作):

新手自学java第一课

# 学习JAVA第一课 如何编写博客 细则 字体 heoll 周毅 方法(星号+内容+星号) heloo周毅 方法(2星号+内容+2星号) heloo周毅 方法(3星号+内容+3星号) heloo周毅 方法(2波浪号+内容+2波浪号) 引用 选择java,走向人生巅峰 方法(小于号+空格)如: 周毅将来一定会成功 分割线 方法(3个---即可) 图片 超链接 点击跳转到周毅的博客 列表 A B C (这是有序列表,方法--1.空格) A B C (这是无序列表,方法:.空格) 表格 姓名 性别

今天新注册的,第一篇文章

以后就不知道啥时候写了,所以来个有纪念性意义的 公元:2014年9月2日21时23分42秒 阴7局干支:甲午年 壬申月 丙子日 己亥时 旬空:辰巳空 戌亥空 申酉空 辰巳空直符:天辅 直使:杜门 旬首:甲午辛┌──────┬──────┬──────┐│癸 白虎○马│戊 六合 │丙 太阴 ││ 天心 己│ 天蓬 丁│ 天任 乙││符 死门 辛│天 惊门 丙│地 开门 癸│├──────┼──────┼──────┤│丁 玄武 │壬 │庚 螣蛇 ││ 天柱 戊│ │ 天冲 壬││蛇 景门 壬│ 庚