I am trying to build generic function to apply rules on DataRows
.
But I am getting following error while running the programe
Here is my code.
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();
}
Function for building expression.
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);
}
and I am calling it in this way in main method.
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();
And below is my Rule
class
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;
}
}
When I run this code I am getting following error.
variable '' of type 'System.Data.DataRow' referenced from scope '', but it is not defined
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: variable '' of type 'System.Data.DataRow' referenced from scope '', but it is not defined
Can somebody please help me out?
Like @svick, I'm getting a different error from the posted code.
Anyway, there are two problems with that BuildExprDataRow
method. First, it's not using the passed param
argument. Second, the property value is not properly converted, so the binary operators does not work.
Here is the fixed method:
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);
}
Btw, the generic argument T
is not used either inside that method, so you can remove it (make the method non generic).