gpt4 book ai didi

c# - 从属性名称的字符串创建表达式?

转载 作者:太空宇宙 更新时间:2023-11-03 17:02:42 25 4
gpt4 key购买 nike

我正在尝试基于一些 JSON 创建查询,我目前将 JSON 解析为一组规则,每条规则包含字段名称、比较类型(=、> 等)和值比较。

我遇到的问题是从该规则获取它到 IQueryable 对象,我猜我需要使用反射并以某种方式构建表达式树,但我不确定正确的方法...

假设我有:

public class Order : BaseEntity
{
public int OrderID{ get; set; }
}

我的规则是:

public class Rule
{
public string field { get; set; }
public Operations op { get; set; }
public string data { get; set; }
}

运行它我得到:

field = "OrderID"
op = "eq"
data = "123"

我有使用签名解析它的方法:

public IQueryable<T> FilterObjectSet<T>(IQueryable<T> inputQuery) where T : class

作为此方法的一部分,我想做的是:

inputQuery = inputQuery.Where(o => propertyInfo.Name == rule1.data);

这不起作用,因为它基本上只生成 sql "OrderID"= "123",这显然是错误的,我需要它从与 propertyInfo.Name 同名的 inputQuery 中获取列名并构建查询那样……

希望这是有道理的?有什么建议吗?

编辑:我猜我想问的是将字符串(因为我可以很简单地根据规则构建一个字符串)转换为表达式,可能使用 Dynamic LINQ?

最佳答案

像这样:

public static IQueryable<T> FilterObjectSet<T>(IQueryable<T> inputQuery, 
Rule rule) where T : class
{
var par = Expression.Parameter(typeof(T));

var prop = Expression.PropertyOrField(par, rule.field);
var propType = prop.Member.MemberType == System.Reflection.MemberTypes.Field ?
((FieldInfo)prop.Member).FieldType :
((PropertyInfo)prop.Member).PropertyType);

// I convert the data that is a string to the "correct" type here
object data2 = Convert.ChangeType(rule.data,
propType,
CultureInfo.InvariantCulture);

var eq = Expression.Equal(prop, Expression.Constant(data2));
var lambda = Expression.Lambda<Func<T, bool>>(eq, par);

return inputQuery.Where(lambda);
}

如果你需要一些解释,你可以问。请注意,这不适用于具有特殊隐式转换的类型(例如 MyString 具有从 string 隐式转换的类型)。这是因为 Convert.ChangeType仅使用 IConvertible界面。

data 的空处理也许是其他应该处理的事情。

请注意,我不确定 Expression.PropertyOrField由各种 IQueryable<T> 处理引擎(LINQ-to-SQL 和 EF)。我只用 AsQueryable() 测试过它引擎。如果他们不“接受”它,您必须将其拆分为 Expression.PropertyExpression.Field取决于什么rule.field是。

不使用 Expression.PropertyOrField 的几乎等效的版本:

public static IQueryable<T> FilterObjectSet<T>(IQueryable<T> inputQuery, 
Rule rule) where T : class
{
Type type = typeof(T);
var par = Expression.Parameter(type);

Type fieldPropertyType;
Expression fieldPropertyExpression;

FieldInfo fieldInfo = type.GetField(rule.field);

if (fieldInfo == null)
{
PropertyInfo propertyInfo = type.GetProperty(rule.field);

if (propertyInfo == null)
{
throw new Exception();
}

fieldPropertyType = propertyInfo.PropertyType;
fieldPropertyExpression = Expression.Property(par, propertyInfo);
}
else
{
fieldPropertyType = fieldInfo.FieldType;
fieldPropertyExpression = Expression.Field(par, fieldInfo);
}

object data2 = Convert.ChangeType(rule.data, fieldPropertyType);
var eq = Expression.Equal(fieldPropertyExpression,
Expression.Constant(data2));

var lambda = Expression.Lambda<Func<T, bool>>(eq, par);
return inputQuery.Where(lambda);
}

关于c# - 从属性名称的字符串创建表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18248676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com