Mehdi
Mehdi

Reputation: 51

Evaluate Conditional Expression

I have a scenario in which I am saving my "if" conditions in database as a string. For example:

String condition = "(([age] >= 28) && ([nationality] == 'US'))";

OR

String condition = "([age] >= 28)";

Now, I want to evaluate that the user has input the condition syntactically correct. These are example of incorrect syntax:

String condition = "(([age] >= 28) && ([nationality] == 'US')"; //Missed ')' bracket

String condition = "[age] >= 28)"; //Missed Opening bracket '('

Like we have in Evaluate Query Expression. Might be Expression tress can be helpful. But how? Need help in this regard.

Upvotes: 5

Views: 4330

Answers (4)

MB_18
MB_18

Reputation: 2251

You could use System.Data and its DataTable.Compute() method.

Here is the code:

public bool CheckCondition()
{
    // parameters
    (string name, object value)[] variables =new (string name, object value)[1];
    variables[0].name = "age";
    variables[0].value = 28;
    variables[1].name = "nationality";
    variables[1].value = "US";

    string conditions = "(([age] >= 28) && ([nationality] == 'US'))";
    conditions.Replace("[", "").Replace("]", "").Replace("&&", "AND").Replace("||", "OR");

    using DataTable table = new DataTable();

    foreach (var (name, value) in variables)
        table.Columns.Add(name, value is null ? typeof(object) : value.GetType());

    table.Rows.Add();

    foreach (var (name, value) in variables)
        table.Rows[0][name] = value;

    table.Columns.Add("_Result", typeof(double)).Expression = conditions
        ?? throw new ArgumentNullException(nameof(conditions));

    return (bool)(Convert.ChangeType(table.Compute($"Min(_Result)", null), typeof(bool)));
}

Upvotes: 0

user3401220
user3401220

Reputation: 1

I found this solution

evaluate an arithmetic expression stored in a string (C#)

SOLUTION:

string conditiontext = "(([age] >= 28) && ([nationality] == \"US\"))";
conditiontext = conditiontext.Replace("[age]", 32)
                             .Replace("[nationality]","US");

/*VsaEngine*/
var engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();

/** Result will be either true or false based on evaluation string*/
var result = Microsoft.JScript.Eval.JScriptEvaluate(conditiontext, engine);

[Note: This interface is deprecated. But it evaluates any arithmetic expressions and c# expressions]

Upvotes: 0

david.s
david.s

Reputation: 11403

Take a look at NCalc. It's a framework for evaluating mathematical expressions.

When the expression has a syntax error, the evaluation will throw an EvaluationException.

try
{
    new Expression("(3 + 2").Evaluate();
}
catch(EvaluationException e)
{
    Console.WriteLine("Error catched: " + e.Message);
}

Though, you can also detect syntax errors before the evaluation by using the HasErrors() method.

Expression e = new Expression("a + b * (");
if(e.HasErrors())
{
    Console.WriteLine(e.Error);
}

Upvotes: 5

SamuelDavis
SamuelDavis

Reputation: 3324

Visual studio doesn't really know what the strings represent so to my knowledge there is no parsing done within the strings themselves.

Typically when programming with C# and using sql, you'd try to do as much of the calculations as possible in C# itself (if it's feasible select the whole table then deal with the result using C#).

If the database is really slow which is quite often the case, it may be useful writing a SQL Builder class to deal with the hardcoded strings.

If you use neither of these methods, unfortunately the best you can really hope for is runtime exceptions (which isn't optimal for obvious reasons).

EDIT: It seems a SelectQueryBuilder library already exists for the second scenario I suggested.

Upvotes: 0

Related Questions