gpt4 book ai didi

c# - Expression.PropertyOrField 为字符串属性返回 "not a member of type ' System.String'"

转载 作者:太空狗 更新时间:2023-10-30 01:16:10 24 4
gpt4 key购买 nike

我正在尝试为规则引擎动态构建表达式并且一切进展顺利,直到我尝试允许将嵌套类型和属性指定为操作数。示例:

表达式生成器

public Expression BuildExpression<T>(string propertyName, Enums.Operator ruleOperator, object value, ParameterExpression parameterExpression)
{
ExpressionType expressionType = new ExpressionType();
Expression body = parameterExpression;

foreach (var member in propertyName.Split('.'))
{
body = MemberExpression.Property(body, member);
}

var leftOperand = MemberExpression.PropertyOrField(body, propertyName);
var rightOperand = Expression.Constant(Convert.ChangeType(value, value.GetType()));
FieldInfo fieldInfo = expressionType.GetType().GetField(Enum.GetName(typeof(Enums.Operator), ruleOperator));
var expressionTypeValue = (ExpressionType)fieldInfo.GetValue(ruleOperator);

return CastBuildExpression(expressionTypeValue, value, leftOperand, rightOperand);
}

规则引擎

public Func<T, bool>[] CombineRules<T>(Criterion[] criteria)
{
List<Func<T, bool>> list = new List<Func<T, bool>>();
foreach (var criterion in criteria)
{
ExpressionBuilder expressionBuilder = new ExpressionBuilder();
var param = Expression.Parameter(typeof (T));
Expression expression = expressionBuilder.BuildExpression<T>(criterion.PropertyName,
criterion.Operator_, criterion.Value, param);
Func<T, bool> func = Expression.Lambda<Func<T, bool>>(expression, param).Compile();
list.Add(func);
}

return list.ToArray();
}

标准

public class Criterion
{
private bool propertySet;
public string PropertyName { get; set; }
public Enums.Operator Operator_ { get; set; }
public object Value { get; set; }

成员模型

public class MemberModel
{
public string UserName{ get; set; }
public PersonalDetailsModel PersonalDetails {get; set;}
}

PersonalDetailsModel

    public class PersonalDetailsModel
{
public int PersonalDetailsId { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Middlename { get; set; }
public string DateOfBirth { get; set; }
public string GenderType { get; set; }
public string SalutationType { get; set; }
}

当我尝试将嵌套属性作为左操作数传递时出现问题,即 PropertyName="PersonalDetails.FirstName"到 ruleEngine.CombineRules(criteria.ToArray());

我得到“‘PersonalDetails.Firstname’不是‘System.String’类型的成员”,尽管它显然是这样。我已经坚持了一段时间,知道是什么原因造成的吗?

如有任何帮助,我们将不胜感激。

最佳答案

这里

    Expression body = parameterExpression;

foreach (var member in propertyName.Split('.'))
{
body = MemberExpression.Property(body, member);
}

你已经处理了属性路径,所以这个

  var leftOperand = MemberExpression.PropertyOrField(body, propertyName);

没有意义,是异常的来源。在您的示例中,body 包含类似 p.PersonalDetails.FirstName (String) 的内容,上面的行试图构建类似 p.PersonalDetails.FirstName.PersonalDetails 的内容.FirstName.

改用 var leftOperand = body;

您可以使用简单的方式缩短整个属性路径处理

var leftOperand = propertyName.Split('.')
.Aggregate((Expression)parameterExpression, Expression.PropertyOrField);

关于c# - Expression.PropertyOrField 为字符串属性返回 "not a member of type ' System.String'",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36222202/

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