【问题标题】:Variable '' of type 'System.Data.DataRow' referenced from scope '', but it is not defined从范围“”引用的“System.Data.DataRow”类型的变量“”,但未定义
【发布时间】:2016-03-18 10:15:28
【问题描述】:

我正在尝试构建通用函数以在 DataRows 上应用规则。

但我在运行程序时遇到以下错误

这是我的代码。

public Func<T, bool> CompileRuleDataRow<T>(Rule r)
{
    var paramUser = Expression.Parameter(typeof(T));
    Expression expr = BuildExprDataRow<T>(r, paramUser);
    // build a lambda function User->bool and compile it
    //Expression.Lambda<Func<T, bool>>(
    return Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
}

构建表达式的函数。

public Expression BuildExprDataRow<T>(Rule r, ParameterExpression param)
{
    ParameterExpression objExpr = Expression.Parameter(typeof(string));
    string defaultMember = "Item";
    ConstantExpression indexExpr = Expression.Constant(r.MemberName);
    Expression leftIndexAccessExpr = Expression.Property(objExpr, defaultMember, indexExpr);
    ExpressionType tBinary;
    // is the operator a known .NET operator?
    ExpressionType.TryParse(r.Operator, out tBinary);
    var right = Expression.Constant(r.TargetValue);
    // use a binary operation, e.g. 'Equal' -> 'u.Age == 15'
    return Expression.MakeBinary(tBinary, leftIndexAccessExpr, right);
}

我在main方法中就是这样调用的。

var rule = new Rule("Name", "Equal", "3");
Func<DataRow, bool> compiledRuleDataRow = CompileRuleDataRow<DataRow>(rule);
DataTable dt = new DataTable();
dt.Columns.Add("Id");
dt.Columns.Add("Name");
dt.Columns.Add("Address");
for (int i = 0; i < 100000; i++)
{
  dt.Rows.Add(i.ToString(), i.ToString(), i.ToString());
}
//I want to do something like this.
    DataRow[] drFiltered = dt.Select().Where(r => compiledRuleDataRow(r)).ToArray();

下面是我的Rule

public class Rule
{
  public string MemberName { get; set; }
  public string Operator { get; set; }
  public string TargetValue { get; set; }

  public Rule(string MemberName, string Operator, string TargetValue)
  {
    this.MemberName = MemberName;
    this.Operator = Operator;
    this.TargetValue = TargetValue;
  }
}

当我运行此代码时,出现以下错误。

从范围''引用的'System.Data.DataRow'类型的变量'', 但没有定义

描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。

异常详细信息:System.InvalidOperationException:变量“” 从范围“”引用的类型“System.Data.DataRow”,但不是 定义

有人可以帮帮我吗?

【问题讨论】:

  • 当我运行您的代码时,我得到一个不同的错误:“实例属性 'Item(String)' 没有为类型 'System.String' 定义”。而且我不明白该代码试图做什么(它试图做一些类似s["Name"]的事情,对于一些未定义的字符串s,这对我来说没有任何意义),所以我不知道怎么做修复它。

标签: c# expression expression-trees rule-engine runtime-compilation


【解决方案1】:

与@svick 一样,我收到的错误与发布的代码不同。

无论如何,BuildExprDataRow 方法存在两个问题。首先,它没有使用传递的param 参数。其次,属性值没有正确转换,所以二元运算符不起作用。

这里是固定方法:

public Expression BuildExprDataRow<T>(Rule r, ParameterExpression param)
{
    var right = Expression.Constant(r.TargetValue);
    var left = Expression.Convert(
        Expression.Property(param, "Item", Expression.Constant(r.MemberName)),
        right.Type);
    var comparison = (ExpressionType)Enum.Parse(typeof(ExpressionType), r.Operator);
    return Expression.MakeBinary(comparison, left, right);
}

顺便说一句,通用参数T 也没有在该方法中使用,因此您可以将其删除(使该方法非通用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2015-10-08
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多