C# 使用反射从属性名获取lambda表达式

C# 使用反射从属性名获取lambda表达式,c#,reflection,entity-framework-4,lambda,C#,Reflection,Entity Framework 4,Lambda,我想让用户选择通过不同的属性进行搜索。比如说 [输入文本]|[选择选项{ID,NAME,PHONE}]|[搜索] 稍后我会像这样构建我的查询: repository.Where(lambda-expression) 其中lambda表达式是从所选选项{ID,NAME,PHONE}生成的 (例如:x=>x.NAME.Equals(输入文本)) 是否有一种方法可以使用反射从属性名构建lambda 谢谢您没有构建lambda表达式,而是构建了一个表达式树。这并不难,但需要一点耐心。在您的示例中,您可

我想让用户选择通过不同的属性进行搜索。比如说

[输入文本]|[选择选项{ID,NAME,PHONE}]|[搜索]

稍后我会像这样构建我的查询:

repository.Where(lambda-expression)
其中lambda表达式是从所选选项{ID,NAME,PHONE}生成的 (例如:x=>x.NAME.Equals(输入文本))

是否有一种方法可以使用反射从属性名构建lambda


谢谢

您没有构建lambda表达式,而是构建了一个表达式树。这并不难,但需要一点耐心。在您的示例中,您可能需要:

ParameterExpression parameter = Expression.Parameter(typeof(Foo), "x");
Expression property = Expression.Property(parameter, propertyName);
Expression target = Expression.Constant(inputText);
Expression equalsMethod = Expression.Call(property, "Equals", null, target);
Expression<Func<Foo, bool>> lambda =
   Expression.Lambda<Func<Foo, bool>>(equalsMethod, parameter); 
ParameterExpression参数=Expression.parameter(typeof(Foo),“x”);
Expression property=Expression.property(参数,propertyName);
表达式目标=表达式常数(inputText);
Expression equalsMethod=Expression.Call(属性“等于”,null,目标);
表达式lambda=
表达式.Lambda(等式方法,参数);
这是假设:

  • 存储库元素类型为
    Foo
  • 您想使用名为
    propertyName
  • 您想与
    inputText

对于这类事情,我使用类似这样的东西(注意:a Where“like”):

公共静态IQueryable Where(此IQueryable源、字符串属性名称、字符串值)
{
表达式,其中Expression=x=>x.GetType().InvokeMember(propertyName,BindingFlags.GetProperty,null,x,null).ObjectToString().IndexOf(value,StringComparison.InvariantCultureIgnoreCase)>=0;
返回源。其中(whereExpression);
}

我不得不面对同样的问题,下面的方法完美地解决了我的问题

PropertyInfo propertyInfoObj = MyClassObject.GetType().GetProperty(PropertyName);
repository.Where(x => propertyInfoObj.GetValue(x) == SearchValue).Select(x => propertyInfoObj.GetValue(x)).FirstOrDefault();

谢谢,它很有魅力。。。一开始我确实遇到了一个错误,我不得不将我的类型从IEnumerable更改为IQueryable,但我应该从使用IQueryable开始。@AJC:你能将该方法设置为泛型方法并将其作为类型参数吗?或者将类型作为普通参数。很难知道该建议什么,因为你没有提供太多的上下文。是的,对不起,我有点懒。我将把类型作为参数传递。。。谢谢…我有个小问题。起初,我对该方法使用了“Contains”,但现在我需要一个“Equals”比较器,我得到了一个错误:类型“System.String”上的多个方法“Equals”与提供的参数兼容。。有什么想法吗?Thanks@AJC:是的,使用另一个重载
表达式。调用
,它使用
方法信息
而不是
字符串
来标识方法。此查询很有用,但当我使用sql profiler检查时,它首先查询所有记录,然后在其上应用表达式。如何只在一个(优化的)查询中获得包含筛选表达式的结果?您是否检查了Sql profiler以查看发出了哪些查询?我有一种感觉,在反射代码运行之前,您会发现整个表都被加载到内存中。
PropertyInfo propertyInfoObj = MyClassObject.GetType().GetProperty(PropertyName);
repository.Where(x => propertyInfoObj.GetValue(x) == SearchValue).Select(x => propertyInfoObj.GetValue(x)).FirstOrDefault();