以前用EF的时候,由于where的时候有Expression<Func<T>>和Func<T>两种查询条件,误用了Func<T>那个重载,后来还想通过func创建查询来着,不过失败了,导致了全表查询,真是无语.国内的人答的比较言简意赅(其实我觉得讲的不好).还是老外讲的明白点.

  翻译过来吧,就是说Func<T>是方法的委托,而Expression<Func<T>>是拉姆达表达式树.这个树状结构描述了各种各样恶心的参数(如下图所示).我们可以用Expression.Compile做成一个委托或者编译成sql(EF).  

Expression<Func<int>> myExpression = () => 10;

  其实吧, 多用一下你就知道了.Func<T>用的还蛮多的,当时就是用来运行泛化的方法的,而Expression<Func<T>>用在动态查询拼接的时候比较多,比如 (And和or,拼接多条表达式树).

public static class PredicateBuilder
{
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose<T>(second, new Func<Expression, Expression, Expression>(Expression.And));
} private static Expression<Func<T, bool>> Compose<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second, Func<Expression, Expression, Expression> merge)
{
Expression expression = new ParameterRebinder(second.Parameters[0], first.Parameters[0]).Visit(second.Body);
return Expression.Lambda<Func<T, bool>>(merge(first.Body, expression), first.Parameters);
} public static Expression<Func<T, bool>> False<T>()
{
return item => false;
} public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> predicate)
{
return Expression.Lambda<Func<T, bool>>(Expression.Not(predicate.Body), predicate.Parameters);
} public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose<T>(second, new Func<Expression, Expression, Expression>(Expression.Or));
} public static Expression<Func<T, bool>> True<T>()
{
return item => true;
} private sealed class ParameterRebinder : ExpressionVisitor
{
private readonly ParameterExpression m_From;
private readonly ParameterExpression m_To; public ParameterRebinder(ParameterExpression from, ParameterExpression to)
{
this.m_From = from;
this.m_To = to;
} protected override Expression VisitParameter(ParameterExpression node)
{
if (node == this.m_From)
{
node = this.m_To;
}
return base.VisitParameter(node);
}
} }

  

表达式树恶心的地方,我写一个orderby给你看看.

        public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);//实体的类型
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "o");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<TEntity>(resultExpression);
}

  动态linq是需要反射的.而且这种写法不利于调试.因为你特么完全不知道生成的什么鬼,除非你对这玩意真的很熟.好吧,你赢了.

参考链接:

Why would you use Expression<Func<T>> rather than Func<T>?

Entity Framework - Func引起的数据库全表查询

通过已有Func构造Expression表达式问题

Expression<Func<T>>和Func<T>的更多相关文章

  1. Expression<Func<T,TResult>>和Func<T,TResult> 与AOP与WCF

    1>>Expression<Func<T,TResult>>和Func<T,TResult>http://www.cnblogs.com/xcsn/p/ ...

  2. Expression<Func<TObject, bool>>与Func<TObject, bool>的区别

    Func<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后 ...

  3. lambda表达式Expression<Func<Person, bool>> 、Func<Person, bool>区别

    前言: 自己通过lambda表达式的封装,将对应的表达式转成字符串的过程中,对lambda表达式有了新的认识 原因: 很多开发者对lambda表达式Expression<Func<Pers ...

  4. Expression<Func<T, bool>>与Func<T, bool>的区别

    转自:http://www.cnblogs.com/wow-xc/articles/4952233.html Func<TObject, bool>是委托(delegate) Expres ...

  5. EF Core 封装方法Expression<Func<TObject, bool>>与Func<TObject, bool>区别

    unc<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后就 ...

  6. expression<Func<object,Bool>> 及 Func<oject,bool>用法

    using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using ...

  7. Expression<Func<T,TResult>>和Func<T,TResult>

    1.Expression<Func<T,TResult>>是表达式 //使用LambdaExpression构建表达式树 Expression<Func<int, ...

  8. 从var func=function 和 function func()区别谈Javascript的预解析机制

    var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同:后者会先于同一语句级的其他语句. 即: { var k = xx(); function ...

  9. onclick="func()"和 onclick = "return func()"区别

    onclick="func()" 表示只会执行 func , 但是不会传回 func 中之回传值onclick = "return func()" 则是 执行 ...

  10. 【转】int const A::func()和int A::func() const

    int const A::func() { return 0; }int A::func() const { return 0; } 上面的代码是合法的,其中A::func成员函数[只能在成员函数后面 ...

随机推荐

  1. ASP.NET MVC一次删除多笔记录 V2.0

    前一段时间Insus.NET有写一篇<ASP.NET MVC一次删除多笔记录>http://www.cnblogs.com/insus/p/6241186.html 可以前往去看看. 觉得 ...

  2. PKI信息安全知识点

    1. 什么是X.509? X.509标准是ITU-T设计的PKI标准,他是为了解决X.500目录中的身份鉴别和访问控制问题设计的. 2. 数字证书 数字证书的意义在于回答公钥属于谁的问题,以帮助用户安 ...

  3. 使用python及工具包进行简单的验证码识别

    相信大家利用 Python 写的爬虫应该遇到过要输入验证码的尴尬局面,又或者写了个自动填充表单的小程序,结果就卡在了验证码上. 在ctf中有⼀一些题⽬目,本身有弱验证码识别绕过,那么我们怎么解决呢? ...

  4. php获取指定日期的前一天,前一月,前一年日期

    ## php获取指定日期的前一天,前一月,前一年日期   前一天的日期为: date("Y-m-d",strtotime("-1 days",strtotime ...

  5. webstorm “Unterminated statement”

    使用webstorm的时候,写console.log,或者一些其他语句的时候  偶尔会出现这种提示,不是报错,就是看着别扭,应该是写法规范问题. 解决办法: 在下面空一行就行了

  6. Flask-SQLAlchemy插件

    一,初始化 两种方式: db = SQLAlchemy() def create_app(): app = Flask(__name__) db.init_app(app) return app ap ...

  7. vue教程2-08 自定义键盘信息、监听数据变化vm.$watch

    vue教程2-08 自定义键盘信息 @keydown.up @keydown.enter @keydown.a/b/c.... 自定义键盘信息: Vue.directive('on').keyCode ...

  8. Task异步编程,刨根到底

    1. 编译器到底对await做了什么 await 一个异步操作的时候,实际上编译器会创建一个状态机,这个状态机包含了调用者的上下文变量,状态机使用yield迭代器实现,状态机由clr调度,每次运行都会 ...

  9. 剑指offer一之二维数组中的查找

    一.题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 二.解答方法: 方法 ...

  10. (转)contextlib — 上下文管理器工具

    原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...