请注明转载地址:http://www.cnblogs.com/arhat

在前几章中,老魏一直使用Linq来查询Entity Framework。但是老魏感觉,如果使用Linq的话,那么Linq的返回值类型有的时候不是很容易找出来,没有直接使用Lambda来的直观,至少在Lambda中我们可以指定返回的类型,这样一来就可以指定返回值了。

在本章的开始呢,老魏先复习一下.NET提供的几个常用的Lambda委托,而这些委托可以说是经常又得到的,尤其实在IEnumerable<T>和 IQueryable<T>的扩展方法中经常的被用到。

常用委托:

1.封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。

public delegate TResult Func<in T, out TResult>(T arg)

这个委托有两个类型参数,一个输入参数和返回值:
in T:此委托封装的方法的参数类型。

out TResult:此委托封装的方法的返回值类型。

那么这个委托怎么用呢?

Func<int,int> f = a=>{return a+;};
int b = f();

结果b=2

2.封装一个具有两个参数并返回 TResult 参数指定的类型值的方法。

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1,T2 arg2)

这个委托有3个类型参数,两个输入参数和返回值:
in T1:此委托封装的方法的第一个参数类型。

in T2:此委托封装的方法的第二个参数类型。

out TResult:此委托封装的方法的返回值类型

那么这个委托怎么用呢?

Func<int,int,int> f = (a,b)=>{return a+b;}
int b = f(,);

结果b=3

Func<int,int,bool> f1 = (a,b)=>{

       if(a==b){

             return true;

       }else{

             return false;

       }

};
bool b = f1(,);

结果:b=false

有了这两个委托后,下面就可以来研究一下IQueryable< T> 接口的扩展方法了,这些扩展方法基本上就是围绕着这两个委托来进行的。

首先我们来看看Where的扩展方法,这个扩展方被重载了四次,但是由于在Ling To Entity中,有二个重载方法不被支持,所以这里就不在对这二个重载函数进行讲解了。

从图上可以看到有四个重载方法,但是对于类型是Expression参数类型的是专门针对Entity Framework的,所以对与没有Expression参数的方法是从IEnumerable<T>中继承过来的。而对于Func<TSource,Int32,Boolean>类型参数的方法是不被Entity Framework支持的。

下面我们主要来看看这个方法:

public static IQueryable<TSource> Where<TSource>(

    this IQueryable<TSource> source,

    Expression<Func<TSource, bool>> predicate

)

类型参数

TSource

source 中的元素的类型。

参数

source

类型: System.Linq.IQueryable<TSource>

要筛选的 IQueryable<T>。

predicate

类型: System.Linq.Expressions.Expression<Func<TSource, Boolean>>

用于测试每个元素是否满足条件的函数。

返回值

类型: System.Linq.IQueryable<TSource>

一个 IQueryable<T>,包含满足由predicate 指定的条件的输入序列中的元素。

需要注意的是凡是实现IQueryable<T>的类基本上都是一个集合类,所以这个参数是判断集合中的每个元素是否满足条件的,所以这个委托的输入参数类型是TSource就是集和中的元素类型,如果这个元素满足条件,则返回一个bool值。

Demo:

List<string> list = new List<string>{“aa”,”bb”,”cccc”,”ff”};

   IQueryable<string> query=list.Where<string>(a=>a.Length>);

当list调用where方法的时候,由于list中存放的元素类型是string所以where的输类型参数也是string,然后看一下输入参数Func<string,bool>,这个委托是用于判断list集合中每个元素的表达式,当满足条件的时候会把这个元素放入一个临时集合中,一直到吧list中所有元素都判断完毕之后,那么临时集合中存放的就是满足条件的元素,然后把这临时的集合返回出去赋值给IEnumrable<string>

下面我们来模拟一下这个where方法的原理:

where<string>(Expresssion<Func<TSource, bool>> predicate)

  {

         IQueryable<string> result = new List<string>();

         foreach(string str in this)

        {

            if(predicate(str))

            {

                list.Add(str);

            }

        }

     return result;

}

当把predicate = a=>{return a.Length>3;}传递给这个函数的时候,在函数的if语句中就会循环的判断这个集合中的元素,把满足的元素添加到临时的list中,最后返回。

下面我们来看看Select方法:

从图上可以看出,这个方法也是重载了4次,齐总Expression是针对Entity Framework的,但是参数Func<TSourse,Int32,TResult>是不被支持的。看到这里的时候,我们会非常的郁闷,Where方法和Select方法都有一个Expression参数的方法,但是Expression是什么,和没有Expression的方法有什么区别吗?其实这是微软对Entity Framework做的一个优化,Expression是“表达式树”,通过Expression可以吧表达式嵌入到SQL语句中形成一个优化的SQL,而没有Expression的方法,不会生成优化的SQL语句,在网上大家可以看看Func<TSource,TResult>陷阱的文章。所以呢,这里我们推荐使用的是Expression类型的表达式树。

public static IQueryable<TResult> Select<TSource, TResult>(

    this IQueryable<TSource> source,

    Expression<Func<TSource, TResult>> selector

)

TSource

source 中的元素的类型。

TResult

由 selector 表示的函数返回的值类型。

参数

source

类型: System.Linq.  IQueryable<  TSource> 
一个要投影的值序列。

selector

类型: System.Linq.Expressions.  ExpressionFunc<  TSource, TResult>  > 
要应用于每个元素的投影函数。

返回值

类型: System.Linq.  IQueryable<  TResult> 
一个 IQueryable<  T>,其元素为对source 的每个元素调用投影函数的结果。

List<Student> list = new List<Student>()

{

      new Student(){SId=,SName="济公",SAge=,SSex="男",CId=},

      new Student(){SId=,SName="飞龙僧",SAge=,SSex="男",CId=},

      new Student(){SId=,SName="刘太真",SAge=,SSex="男",CId=},

      new Student(){SId=,SName="玉面仙姑",SAge=,SSex="女",CId=},

      new Student(){SId=,SName="东方太悦",SAge=,SSex="男",CId=},

      new Student(){SId=,SName="无语老祖",SAge=,SSex="男",CId=},

      new Student(){SId=,SName="黄淑女",SAge=,SSex="女",CId=}

};

IQueryable<string> query = list.Select<Student, string>(student => student.SName);

foreach (string name in query)
{
Console.WriteLine(name);
}

在使用select方法的时候,指定了集合中的元素类型和返回值中的元素类型。其中要查询的集合元素类型为Student,而返回值的类型是string。所在在lambda中我们指定返回student.SName类型。

当然了,我们还可以指定多个列。代码如下:

IQueryable<List<string>> query = list.Select<Student, List<string>>(student => { return new List<string> { student.SName, student.SAge + "" }; });

   foreach (List<string> row  in query)

   {

         Console.WriteLine(row[] + "  " + row[]);

   }

在这个方法中,我们指定了返回的类型是List<string>。所以在Lambda中我们创建了一个List<string>对象,用于保存每个元素的SName,SAge两个属性。这里需要注意的是在List<student>中的每个元素的SName,SAge都是一个List<string>。

本章就写到这里吧,本章之讲解了Where和Select两个扩展方法,东西不多,但是对于那些还停留在入门的朋友来说,可以作为参考文章。那么在接下来的文章中,老魏还会继续探讨一下这些常用的扩展方法,并通过实例来显示这些方法在Entity Framework中怎么使用。希望能给大家带来帮助!顺便这里老魏说一下,发表文章的时间还是不确定,因为时间有限,所以只能在闲暇的时间来写文章了。

Entity Framework学习笔记(六)----使用Lambda查询Entity Framework(1)的更多相关文章

  1. IBatis.Net学习笔记六--再谈查询

    在IBatis.Net学习笔记五--常用的查询方式 中我提到了一些IBatis.Net中的查询,特别是配置文件的写法. 后来通过大家的讨论,特别是Anders Cui 的提醒,又发现了其他的多表查询的 ...

  2. MYSQL初级学习笔记六:子查询!(视频序号:初级_42 | 43)

    知识点八:子查询(42) 什么是子查询: 子查询是将一个查询语句嵌套在另一个查询语句中.内层查询语句的查询结果,可以作为外层查询语句提供条件. 引发子查询的情况: 使用[NOT] IN 的子查询 -- ...

  3. Entity Framework学习笔记

    原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总   之前的小项目做完了,到了总结经验和 ...

  4. ADO.NET Entity Framework学习笔记(3)ObjectContext

    ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转]   说明 ObjectContext提供了管理数据的功能 Context操作数据 AddObject ...

  5. Entity Framework 学习笔记(2)

    上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...

  6. Programming Entity Framework-dbContext 学习笔记第五章

    ### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...

  7. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  8. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  9. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

随机推荐

  1. Nginx负载趟过的坑

    在项目中经常会碰到需要利用Nginx作负载,最近在利用Nginx作负载均衡器时碰到一个很奇葩的问题. 本来按照以前的实现将打好的A.war包直接放到tomcat根目录(webapps)下,然后按照如下 ...

  2. js中关于数据类型的转换

    * 一.转化为数字*/console.log(‘123123’*1.0); /* 二.从一个值中提取另一中类型的值,并完成转化工作 */console.log(parseInt(‘1233zxhag’ ...

  3. JS测试浏览器类型的代码

    function getOs(url,title) { var OsObject = ""; if(navigator.userAgent.indexOf("MSIE&q ...

  4. .NET DLL 保护措施详解(三)最终效果

    针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...

  5. 安卓、java开发软件官网和相关不错的网站软件下载地址

    java:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html eclipse:htt ...

  6. Android 开源项目分类汇总

    Android 开源项目分类汇总 Android 开源项目第一篇——个性化控件(View)篇  包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView ...

  7. Android TintResources Leak

    在使用Android WebView的时候,可能会造成Activity的内存泄漏,这个是Android的Bug,目前发现在WebView内部在使用TintResources时会发生内存泄漏,但是在ap ...

  8. .Net的基础概念

    1,参数传递. 默认都是按值传递(无论引用还是值类型),也就意味着传递参数的一个副本给方法.之后在方法体内对参数的更改,对原始参数没有影响. 使用ref/out可以按引用传递,直接影响原始参数变量.两 ...

  9. Codevs 1014 装箱问题

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若 ...

  10. C语言实现基于投票规则的细胞自动机

    算法介绍 首先我们先看一下“基于投票规则的细胞自动机”的定义: 基于投票规则的细胞自动机,实际上是具有如下限定条件的一种细胞自动机: 状态:0或1: 邻居:中心的3*3邻居: 规则:计数p表示中心的3 ...