1.Func<Student, bool>和Expression<Func<Student, bool>>的区别

    class Program
{
static void Main(string[] args)
{
Func<Student, bool> func = t => t.Name == "";
//匿名函数
Expression<Func<Student, bool>> expression = t => t.Name == "";
//表达式树 有Body Right、Left,Right里面又有Right、Left,它们的类型都是继承自 Expression 。这种节点下面有节点,可以无限附加下去的数据结构我们称为树结构数据。也就是我们的表达式树。
Console.Read();
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
}

2.解析表达式树

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; namespace RedisTest
{
class Program
{
static void Main(string[] args)
{
Expression<Func<Student, bool>> expression = t => t.Name == "" && t.Name == "";
AnalysisExpression.VisitExpression(expression);
/*
运算符:AndAlso
运算符:Equal
字段名称:Name,类型:System.String
常量值:1111
运算符:Equal
字段名称:Name,类型:System.String
常量值:2222
*/
Console.Read();
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
} public static class AnalysisExpression
{
public static void VisitExpression(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.Call://执行方法
MethodCallExpression method = expression as MethodCallExpression;
Console.WriteLine("方法名:" + method.Method.Name);
for (int i = ; i < method.Arguments.Count; i++)
VisitExpression(method.Arguments[i]);
break;
case ExpressionType.Lambda://lambda表达式
LambdaExpression lambda = expression as LambdaExpression;
VisitExpression(lambda.Body);
break;
case ExpressionType.Equal://相等比较
case ExpressionType.AndAlso://and条件运算
BinaryExpression binary = expression as BinaryExpression;
Console.WriteLine("运算符:" + expression.NodeType.ToString());
VisitExpression(binary.Left);
VisitExpression(binary.Right);
break;
case ExpressionType.Constant://常量值
ConstantExpression constant = expression as ConstantExpression;
Console.WriteLine("常量值:" + constant.Value.ToString());
break;
case ExpressionType.MemberAccess:
MemberExpression Member = expression as MemberExpression;
Console.WriteLine("字段名称:{0},类型:{1}", Member.Member.Name, Member.Type.ToString());
break;
default:
Console.Write("UnKnow");
break;
}
} }
}

3.认识IQueryable和IQueryProvider接口

ElementType 代表当然这个Query所对应的类型
Expression 包含了我们当然Query所执行的所有查询或者是其它的操作
IQueryProvider则是负责处理上面的Expression的实现

IQueryProvider只有两个操作,CreateQuery和Execute分别有泛型版本和非泛型版本。 CreatQuery用于构造一个IQueryable<T>的对象,这个类其实没有任何实现,只是继承了IQueryable和IEnumrable接口。主要用于计算指定表达式目录树所表示的查询,返回的结果是一个可枚举的类型。 而Execute会执行指定表达式目录树所表示的查询,返回指定的结果。

4.实现自己的IQueryable<T>、IQueryProvider

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; namespace RedisTest
{
class Program
{
static void Main(string[] args)
{
var aa = new MyQueryable<Student>();
var bb = aa.Where(t => t.Name == "");
var cc = bb.Where(t => t.Sex == "男");
var dd = cc.AsEnumerable();
var ee = cc.ToList();
//每次在执行 Where 查询操作符的时候都会把lambda转化为express存放在MyQueryable的Expression里
//调用 AsEnumerable() 方法的时候并不会去实际取值(只是得到一个IEnumerable)[注意:在EF里面查询不要先取IEnumerable后滤筛,因为AsEnumerable()会生成查询全表的sql]
//执行 ToList() 方法时才去真正调用迭代器 GetEnumerator() 取值
//真正取值的时候,会去执行 IQueryProvider 中的 Execute 方法。(就是在调用这个方法的时候解析表达式数,然后执行取得结果)
//我们看到真正应该办实事的 Execute 我们却让他返回默认值了。
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
} public class MyQueryProvider : IQueryProvider
{
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new MyQueryable<TElement>(expression);
} public IQueryable CreateQuery(Expression expression)
{
throw new NotImplementedException();
} public TResult Execute<TResult>(Expression expression)
{
return default(TResult);
} public object Execute(Expression expression)
{
return new List<object>();
}
}
public class MyQueryable<T> : IQueryable<T>
{
public MyQueryable()
{
_provider = new MyQueryProvider();
_expression = Expression.Constant(this);
} public MyQueryable(Expression expression)
{
_provider = new MyQueryProvider();
_expression = expression;
}
public Type ElementType
{
get { return typeof(T); }
} private Expression _expression;
public Expression Expression
{
get { return _expression; }
} private IQueryProvider _provider;
public IQueryProvider Provider
{
get { return _provider; }
} public IEnumerator GetEnumerator()
{
return (Provider.Execute(Expression) as IEnumerable).GetEnumerator();
} IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
var result = _provider.Execute<List<T>>(_expression);
if (result == null)
yield break;
foreach (var item in result)
{
yield return item;
}
}
}
}

再一个例子

    class Program
{
static void Main(string[] args)
{
var DB = new wolf_testEntities();
decimal aa = ;
ParameterExpression pExpression = Expression.Parameter(typeof(People));
var getPropertyValue = Expression.Property(pExpression, typeof(People).GetProperty("Num"));
ConstantExpression cExpression = Expression.Constant(aa);
BinaryExpression bExpression = Expression.MakeBinary(ExpressionType.GreaterThan, getPropertyValue, cExpression);
Expression<Func<People, bool>> lambda = Expression.Lambda<Func<People, bool>>(bExpression, pExpression);
//Expression Tree 的条件 x=>x.Num>0
var bbb = DB.People.Where(lambda).ToList();
Console.ReadLine();
}
}

认识IQueryable和IQueryProvider接口的更多相关文章

  1. IQueryable和IQueryProvider初尝

    前言 相信大家对Entity Framework一定不陌生,我相信其中Linq To Sql是其最大的亮点之一,但是我们一直使用到现在却不曾明白内部是如何实现的,今天我们就简单的介绍IQueryabl ...

  2. IQueryable 与 IEnumberable 接口的区别

    IQueryable 与 IEnumberable 接口的区别是: IEnumberable<T> 泛型类在调用自己的 SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了, ...

  3. .NET架构设计、框架设计系列文章总结

    从事.NET开发到现在已经有七个年头了.慢慢的可能会很少写.NET文章了.不知不觉竟然走了这么多年,热爱.NET热爱c#.突然想对这一路的经历进行一个总结. 是时候开始下一阶段的旅途,希望这些文章可以 ...

  4. .NET系列文章——近一年文章分类整理,方便各位博友们查询学习

    由于博主今后一段时间可能会很忙(准备出书:<.NET框架设计—模式.配置.工具>,外加换了新工作),所以博客会很少更新: 在最近一年左右时间里,博主各种.NET技术类型的文章都写过,根据博 ...

  5. NET系列文章

    NET系列文章 由于博主今后一段时间可能会很忙(准备出书:<.NET框架设计—模式.配置.工具>,外加换了新工作),所以博客会很少更新: 在最近一年左右时间里,博主各种.NET技术类型的文 ...

  6. .NET深入解析LINQ框架2

    1].开篇介绍 在开始看本篇文章之前先允许我打断一下各位的兴致.其实这篇文章本来是没有打算加“开篇介绍”这一小节的,后来想想还是有必要反馈一下读者的意见.经过前三篇文章的详细讲解,我们基本上对LINQ ...

  7. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  8. 不可不知的表达式树(3)定制IQueryProvider

    前面我们说到利用表达式树技术实现LINQ-to-SQL,实际上可以针对任何数据源,实现LINQ-to-Everything.这里还涉及到两个重要的接口即IQueryable和IQueryProvide ...

  9. 【转】再讲IQueryable<T>,揭开表达式树的神秘面纱

    [转]再讲IQueryable<T>,揭开表达式树的神秘面纱 接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个 ...

随机推荐

  1. javascript高级程序语言学习笔记

    1.加法操作符(+)的用法 第一种情况,如果两个操作符都是数值,执行常规的加法计算. 第二种情况,如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来. 第三种情况,只有一个操作数是字符串 ...

  2. ios webview调试

    chrome://inspect/#devices if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKAT) { WebView.setWe ...

  3. Redis学习之一 安装

    一.简介 定义 Remote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C ...

  4. hibernate框架学习之数据查询(QBC)helloworld

    package cn.itcast.h3.query.hql; import java.util.List; import org.hibernate.Criteria; import org.hib ...

  5. MariaDB基础详解

    数据库结构模型分类 1.层次模型 2.网状模型 3.关系模型 关系模型的组成部分 二维关系 表 row column 索引 index 视图 view (只包含固定字段,不包含其他字段) 关系型数据库 ...

  6. Light OJ 1214

    简单大数模拟题: #include<bits/stdc++.h> using namespace std; typedef long long ll; string Num; vector ...

  7. zipkin 整合elastic

    前提: <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin</ar ...

  8. python-re模块和subprocess模块

    一.re模块 re中文为正则表达式,是字符串处理的常用工具,通常用来检索和替换符合某个模式的文本. 注:要搜索的模式和字符串都可以是unicode字符串(str)和8位字符串(bytes),但是不能将 ...

  9. Android性能优化之图片压缩优化

    1 分类Android图片压缩结合多种压缩方式,常用的有尺寸压缩.质量压缩.采样率压缩以及通过JNI调用libjpeg库来进行压缩. 参考此方法:Android-BitherCompress 备注:对 ...

  10. hdu2602 Bone Collector 01背包

    Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like ...