【发布时间】:2018-08-22 10:36:09
【问题描述】:
我不习惯使用表达式函数,但我的问题是: 我将属性名称作为字符串获取,然后我需要将其转换为适当的表达式。
目前我正在做这样的事情:
if (string.Equals(propertyString, "customerNo", StringComparison.InvariantCultureIgnoreCase))
{
return _repo.DoSomething(x=>x.CustomerNo);
}
if (string.Equals(propertyString, "customerName", StringComparison.InvariantCultureIgnoreCase))
{
return _repo.DoSomething(x => x.CustomerName);
}
使用 repo 函数是这样的:
public IEnumerable<ICustomer> DoSomething(Expression<Func<IObjectWithProperties, object>> express)
{
//Do stuff
}
我想做的是像这样使用反射:
var type = typeof(IObjectWithProperties);
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
if(string.Equals(property.Name,propertyString,StringComparison.InvariantCultureIgnoreCase))
return _repo.DoSomething(x => x.PROPERTY);
}
但我想不出一种从 propertyinfo 生成表达式 func 的方法
编辑:Mong Zhu 的回答,我可以使用该属性创建一个表达式。
我需要这个表达式的原因是我试图在 iqueryable 中动态设置 orderby。
public IEnumerable<Customer> List(Expression<Func<IObjectWithProperties, object>> sortColumn)
{
using (var context = _contextFactory.CreateReadOnly())
{
return context.Customers.OrderBy(sortColumn).ToList();
}
}
使用这样的答案:
public Customer Test(string sortColumn){
var type = typeof(IObjectWithProperties);
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
if (string.Equals(property.Name, sortColumn, StringComparison.InvariantCultureIgnoreCase))
{
Expression<Func<IObjectWithProperties, object>> exp = u =>
(
u.GetType().InvokeMember(property.Name, BindingFlags.GetProperty, null, u, null)
);
return _customerRepository.List(exp);
}
}
}
我收到一个错误:
System.InvalidOperationException:从范围“”引用的“IObjectWithProperties”类型的变量“u”,但未定义
编辑:
Customer 返回类型继承 IObjectWithProperties:
public class Customer: IObjectWithProperties
{
//properties
}
【问题讨论】:
-
“我得到一个属性的名称作为字符串”你从哪里得到它?用户输入?你能影响来源吗?
-
来自控制器,遗憾的是我无法控制这个
-
可能 Customer 是一个
partial class,作为现有数据库模型的扩展? -
没错是的
-
好的,我学到了很多关于表达式树的知识。从适用性和特别是可读性的角度来看,我建议您继续使用 if/else 方法。我想它可以解决,但工作量很大,我猜可读性会受到影响
标签: c# reflection lambda expression