• Func委托与表达式树Expression


    最近在写ORM框架,其中遇到一个难点,就是作为框架调用方如何将查询条件传入框架内。其中就用到了Expression。


    Func委托

    要Expression先要了解Func委托,Func委托的样式是:

    Func<T,TResult>

    他是一种C#提供的固定的委托方法,算是微软提供的一种语法糖。

    举例说明:

    1 //声明
    2 Func<int, int> func = f => f + 1;
    3 //调用
    4 int funcResult=func(1);
    5 
    6 //结果=2

    其中,Func<int, int>中第一个int是参数类型,第二个int是返回值类型。

    Func<int, int> func = f => f + 1;等号后跟表达式中的参数,=>是lambda表达式的运算符,后跟方法体。

    与下面这种正常的委托写法是一样的效果:

    声明委托类型:

    delegate int Function(int f);

    赋值委托方法:

    int ffunc(int f)
    {
        return f + 1;
    }
    //声明委托对象
    Function function;
    //赋值对象
    function = ffunc;
    int ffuncResult = function(1);

    其中我们可以看出来,不管是上面Func的写法还是delegate写法,都是相当于把方法作为参数进行传递。

    注意Func只能传递一个参数,但是可以自定义对象作为参数类型变相的传递多个参数。


    Expression表达式树

    理解了委托和上面的Func委托Expression就很容易理解了。

    先看Expression的官方文档是怎么说的:

     

    ~~好吧,官方文档实在看不懂,那F12一下:

     

    这里就能看出来了一部分内容,Expression是要使用委托类型的,而且只能是lambda表达式类型的委托,所以最好就是Func委托,这也是为什么刚开始我要讲Func委托的原因。

    他的使用形式上是这样的:

    Expression<Func<T,TResult>>

    可以看出他是在委托上又嵌套了一层,就像树一样,“委托树”,因为只能嵌套lambda表达式,所以官方叫法是表达式树

    那要怎么用呢?此处列举一种用法,就是我开头提到的获取对象的属性名称。

    声明实体:

    public class Class2
    {
        public string A1 { get; set; }
        public int? A2 { get; set; }
    }

    获取属性名称方法:

    //获取属性名称
    string ConvertOrderBy<TEntity>(Expression<Func<TEntity, object>> orderby) where TEntity : class
    {
        var member = orderby.Body as MemberExpression;
        var unary = orderby.Body as UnaryExpression;
        return member != null ? member.Member.Name : (unary != null ?         (unary.Operand as MemberExpression).Member.Name : null);
    }
    string SetOrderBy<TEntity>(Expression<Func<TEntity,object>> orderBy) where TEntity : class
    {
        return ConvertOrderBy(orderBy);
    }
    var linqStr = SetOrderBy<Class2>(s => s.A2);

    运行结果:


    总结

    Expression在EF框架中存在大量使用,主要是需要框架底层需要知道传入属性的名称和类型。在使用时一定要注意Expression中一定只能是lambda表达式类型的委托。

    如果觉得不错,可以推荐收藏一下,让我也更有动力。
  • 相关阅读:
    JavaScript 操作 DOM 元素
    字节数
    如何判断校准曲线是否合格
    [WPF]MVVM模式下如何在后台cs中调用绑定命令
    逆对数antilog0.03376如何计算
    未能解析此远程名称:'nuget.org' 的解决方法
    【WPF】WPF ScorllView触摸滚动实现
    【VS2017】清除NuGet下载旧版本缓存
    【UWP】截图
    test
  • 原文地址:https://www.cnblogs.com/jingboweilan/p/13538838.html
Copyright © 2020-2023  润新知