问题
My .NET application evaluates user defined rules at runtime. These rules are entered to system via GUI menus by user. I generate a logical statement that corresponds to it and store it in database.
For example: (Name = 'John' AND Surname = 'Smith') OR Number > 12
However, when the user wants to edit a rule by GUI, I need to make a reverse operation to determine menu states from the stored rule, which is costly and complex. How would you recommend to store rules in a way that it can be reversed to menu states easily?
回答1:
You could store the rules as ASTs - implement a few classes that represent the nodes of the tree:
interface INode
{
}
enum BinaryOperator
{
AND, OR, Equal, Greater, Lower;
}
class BinaryExpression : INode
{
BinaryOperator Operator { get; set; }
INode Left { get; set; }
INode Right { get; set; }
}
class PropertyRerefence : INode
{
string PropertyName { get; set; }
}
class Constant : INode
{
string Value { get; set; }
}
The tree for your example would look like this:
BinaryExpression(OR)
Left=BinaryExpression(AND)
Left=...
Right=...
Right=BinaryExpression(Greater)
Left=PropertyReference("Number")
Right=Constant("12")
You could then use serialization (best JSON, or XML, maybe even binary if you don't care about readability in the db) to save such trees. On deserialization, you don't need to do any parsing and can traverse the tree to populate the menus.
Printing "(Name = 'John' AND Surname = 'Smith') OR Number > 12" is also easy when you have the AST - for a BinaryExpression: print Left, print Operator, print Right.
You say you already have the evaluation implemented so I'll leave this out. You can also look at this question.
来源:https://stackoverflow.com/questions/6444845/rule-engine-how-to-store-rules-to-avoid-parsing-on-edit