前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#笔记:用Expressions表达式自动生成linq查询

C#笔记:用Expressions表达式自动生成linq查询

作者头像
超级大猪
发布2019-11-22 09:46:05
1.3K0
发布2019-11-22 09:46:05
举报
文章被收录于专栏:大猪的笔记大猪的笔记
代码语言:javascript
复制
string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
                               "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
                               "Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
                               "Blue Yonder Airlines", "Trey Research", "The Phone Company",
                               "Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };
           
            IQueryable<String> queryableData = companies.AsQueryable<string>(); 
            //首先,要把需要查询的数据源先准备好
            
            ParameterExpression pe = Expression.Parameter(typeof(string), "company");
            //我们可以把它当作 linq lambda式中的一个常量,比如 company=>company
           
            Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
            //执行完这句,我们得到了一个式子 company.ToLower(),前面的常量发挥了作用
            
            Expression right = Expression.Constant("coho winery");
            //我们得到了一个string类型的变量 coho winery
            
            Expression e1 = Expression.Equal(left, right);
            //我们得到了 company.ToLower() == "coho winery"
            
            left = Expression.Property(pe, typeof(string).GetProperty("Length"));
            // pe 就是简单的常量 company ,这句就是 company.Length
            
            right = Expression.Constant(16, typeof(int));
            // 16
            
            Expression e2 = Expression.GreaterThan(left, right);
            // company.Length > 16
            
            Expression predicateBody = Expression.OrElse(e1, e2);
            //  company.ToLower() == "coho winery" || company.Length > 16
    
            //接下来就耐人寻味了
            MethodCallExpression whereCallExpression = Expression.Call(
                typeof(Queryable),  
                //我们要查的元素是Queryable 类型
                
                "Where", 
                //Queryable 类型中有个Where方法
                
                new Type[] { queryableData.ElementType }, 
                //这个指的是Where<T> 中的T应该为什么元素,显然下面的OrderBy函数 其实是OrderBy<TSource, TKey>。必须指定type
                
                queryableData.Expression, 
                //这个可以简单理解为是什么东西(的方法簇)需要调用Where方法。显然是我们指定的data需要。
                
                Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { pe }
                //传入的是一个lambda表达式。这个比较耐人寻味。传入的是company,显然是string类型。
                //company.ToLower() == "coho winery" || company.Length > 16 返回的显然是bool类型的值
                // 至于后面,第二个参数可以想像为 => 左边的东西。第一个参数是表达式,在 =>右边。
            ));
        
            // 简单说来就是,先指定调用method的源的类型。
            //再指定method的方法名。
            //再指定这个方法如果是泛型,需要传入的类型type
            //再指定源的实体
            //再指定传入参数的实体。这样一个MethodCallExpression就生产出来了。好了该睡觉了。
            
            MethodCallExpression orderByCallExpression = Expression.Call(
                typeof(Queryable),
                "OrderBy",
                new Type[] { queryableData.ElementType, queryableData.ElementType },
                whereCallExpression,
                Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));
          
          
            IQueryable<string> results = queryableData.Provider.CreateQuery<string>(orderByCallExpression);
          
            foreach (string company in results)
                Console.WriteLine(company);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-02-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档