【问题标题】:Rule Engine - How to store rules to avoid parsing on edit?规则引擎 - 如何存储规则以避免在编辑时解析?
【发布时间】:2011-06-22 18:39:12
【问题描述】:

我的 .NET 应用程序在运行时评估用户定义的规则。这些规则由用户通过 GUI 菜单输入到系统中。我生成一个与之对应的逻辑语句并将其存储在数据库中。

例如:(Name = 'John' AND Surname = 'Smith') OR Number > 12

但是,当用户想要通过 GUI 编辑规则时,我需要进行反向操作,从存储的规则中确定菜单状态,这既昂贵又复杂。您如何建议以可以轻松反转为菜单状态的方式存储规则?

【问题讨论】:

  • 这在很大程度上取决于您支持哪些规则以及您为用户提供了多少灵活性。
  • 如果你的规则很复杂,实现一个既定的业务规则引擎而不是自己编写规则管理是有意义的。规则不仅仅是简单的 GUI 菜单和动态语句生成。

标签: .net sql rule-engine business-rules rule


【解决方案1】:

您可以将规则存储为ASTs - 实现一些代表树节点的类:

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,如果您不关心数据库中的可读性,甚至可能是二进制)来保存此类树。在反序列化时,您不需要进行任何解析,并且可以遍历树来填充菜单。

当您拥有 AST 时,打印“(Name = 'John' AND Surname = 'Smith') OR Number > 12”也很容易 - 对于 BinaryExpression:print Left,print Operator,print Right。

您说您已经实施了评估,所以我将忽略这一点。也可以看this question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2010-09-10
    • 2019-09-18
    相关资源
    最近更新 更多