我的.NET应用程序在运行时评估用户定义的规则。 这些规则由用户通过GUI菜单输入到系统中。 我生成一个对应于它的逻辑语句并将其存储在数据库中。
例如:(Name ='John'AND Surname ='Smith')OR Number> 12
但是,当用户想要通过GUI编辑规则时,我需要进行反向操作以从存储的规则中确定菜单状态,这是昂贵且复杂的。 您如何建议以一种可轻松颠倒菜单状态的方式存储规则?
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?
最满意答案
您可以将规则存储为AST s - 实现一些代表树的节点的类:
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; } }您示例中的树将如下所示:
BinaryExpression(OR) Left=BinaryExpression(AND) Left=... Right=... Right=BinaryExpression(Greater) Left=PropertyReference("Number") Right=Constant("12")然后,您可以使用序列化(最好的JSON或XML,如果您不关心数据库中的可读性,则可能是二进制文件)来保存这些树。 在反序列化中,您不需要执行任何解析并可以遍历树来填充菜单。
打印“(名称='约翰'和姓='史密斯')或编号> 12”也很容易,当你有AST - 对于BinaryExpression:打印左,打印操作员,打印右。
你说你已经完成了评估,所以我会放弃这一点。 你也可以看看这个问题 。
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.
更多推荐
发布评论