首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >手动创建Lambda表达式用作where谓词

手动创建Lambda表达式用作where谓词
EN

Stack Overflow用户
提问于 2015-09-02 12:57:10
回答 1查看 286关注 0票数 0

我试图使用lambda表达式作为通过反射调用IEnumerable.Where的谓词。

e.Query是System.Data.Objects.ObjectQuery<T>类型的,在运行时T是已知的。ObjectQuery实现了IEnumerable。

代码语言:javascript
复制
//the current element type
Type currentType = e.Query.ElementType;

ParameterExpression typeParameterExpression = Expression.Parameter(currentType);
ConstantExpression propertyConstantExpression = Expression.Constant(GameId, GameId.GetType());
BinaryExpression equalityExpression = Expression.Equal(Expression.PropertyOrField(typeParameterExpression, "GameId"), propertyConstantExpression); 

Type genericFunc = typeof(Func<,>).MakeGenericType(currentType, typeof(bool)); //genericFunc = {Name = "Func`2" FullName = "System.Func`2[[OfferManagementBackOffice.Placement, OfferManagementBackOffice, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
Expression predicateExpression = Expression.Lambda(genericFunc, equalityExpression, typeParameterExpression); //predicateExpression = {Param_0 => (Param_0.GameId == 2)}

var whereMethods = typeof(System.Linq.Enumerable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");
MethodInfo whereMethod = null;
foreach (var methodInfo in whereMethods)
{
    var paramType = methodInfo.GetParameters()[1].ParameterType;
    if (paramType.GetGenericArguments().Count() == 2)
    {
        // we are looking for  Func<TSource, bool>, the other has 3
        whereMethod = methodInfo;
    }
}

whereMethod = whereMethod.MakeGenericMethod(currentType);
//whereMethod = {System.Collections.Generic.IEnumerable`1[OfferManagementBackOffice.Placement] Where[Placement](System.Collections.Generic.IEnumerable`1[OfferManagementBackOffice.Placement], System.Func`2[OfferManagementBackOffice.Placement,System.Boolean])}

var result = whereMethod.Invoke(e.Query, new object[] { e.Query, predicateExpression });

当我在whereMethod上尝试调用()时,我得到了以下错误:

错误:无法将'System.Linq.Expressions.Expression``1[System.Func``2[OfferManagementBackOffice.Placement,System.Boolean]]'类型的对象转换为'System.Func``2[OfferManagementBackOffice.Placement,System.Boolean]'类型。

我想要实现的是这个(这里是T= Placement),但是对于任何类型。

代码语言:javascript
复制
Expression<Func<Placement, bool>> lambda1 = Expression.Lambda<Func<Placement, bool>>(equalityExpression, typeParameterExpression);
e.Query.Cast<Placement>().Where(lambda1);
EN

回答 1

Stack Overflow用户

发布于 2015-09-02 13:38:51

首先,我要感谢@Grundy抽出时间来帮助我找到解决这个问题的方法:

为了使Where调用工作,我必须使用lambda表达式.Compile()

代码语言:javascript
复制
var predicateExpression = Expression.Lambda(genericFunc, equalityExpression, typeParameterExpression).Compile();

这是可行的,但它返回一个WhereEnumerableIterator<T>而不是所需的ObjectQuery。

事实证明,我需要使用Queryable.Where而不是Enumerable.Where。但是现在,由于一些奇怪的原因,我不需要(实际上我不能)编译lambda表达式才能工作。下面是最后的工作代码:

代码语言:javascript
复制
short GameId = Convert.ToInt16(Session["GlobalGameFilter"]);
Type currentType = e.Query.ElementType;

ParameterExpression typeParameterExpression = Expression.Parameter(currentType);
ConstantExpression propertyConstantExpression = Expression.Constant(GameId, GameId.GetType());
BinaryExpression equalityExpression = Expression.Equal(Expression.PropertyOrField(typeParameterExpression, "GameId"), propertyConstantExpression);

Type genericFunc = typeof(Func<,>).MakeGenericType(currentType, typeof(bool));
var predicateExpression = Expression.Lambda(genericFunc, equalityExpression, typeParameterExpression);

var whereMethods = typeof(System.Linq.Queryable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");
MethodInfo whereMethod = whereMethods.ElementAt(0).MakeGenericMethod(currentType);


var result = whereMethod.Invoke(e.Query, new object[] { e.Query, predicateExpression });

e.Query = (IQueryable)result;

现在的结果是ObjectQuery类型,这正是我所需要的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32353834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档