• 认识IQueryable和IQueryProvider接口


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

        class Program
        {
            static void Main(string[] args)
            {
                Func<Student, bool> func = t => t.Name == "1111";
                //匿名函数
                Expression<Func<Student, bool>> expression = t => t.Name == "1111";
                //表达式树 有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 == "1111" && t.Name == "2222";
                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 = 0; 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 == "1234");
                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 = 0;
                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();
            }
        }
  • 相关阅读:
    机器学习--决策树
    插入排序、选择排序的实现与性能比较
    【笔记】如何实现属性可修改的函数装饰器
    【笔记】如何为被装饰的函数保存元数据
    【笔记】对文件的一些操作
    【笔记】对字符串的一些操作
    USB鼠标按键驱动
    LCD驱动 15-3
    LCD驱动 15 -2
    LCD驱动 15-1
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/6762520.html
Copyright © 2020-2023  润新知