持久化布尔逻辑

本文关键字:布尔逻 持久化 | 更新日期: 2023-09-27 17:50:56

这是一种与设计相关的问题,而不是技术问题。标题可能不完美,请随意编辑。

我有如下要求:我想从表中保存SQL Server 2012中特定jobEntity(不要与SQL Server作业混淆)的资格。出于同样的目的,我有另一个表说资历,它保存以上的资历与工作,有一个参照完整性的工作表。执行此操作的存储过程具有参数JobID和用户定义的模式表类型:

CREATE TYPE [dbo].[TableTypeQualificationJob] AS TABLE(
    [QualificationID] [int] NULL,
    [QualificationCriteria] [nvarchar](4000) NULL,
    [OptionTo] [bigint] NULL
)
GO

我在业务层有相应的实体。因此,当用户为工作创建多个资格时,他将List传递给函数,底层方法将List转换为数据表,并使用存储过程将其添加到数据库中。

问题在于OR或AND中的限定符can。例:如果有5个条件说qualification1qualification2qualification3qualification4qualification5

并强制执行到工作

qualiation1或qualiation2或qualiation3和qualiation4和qualification5

所以它组成了三个组

(qualiation1 OR qualiation2 OR qualiation3) AND(qualiation4) AND (qualiation5)

那么我如何在qualiationentity类和数据库中解释它。我正在使用ADO呼叫SP。. NET通过手动将列表转换为用户定义的表类型的DataTable,我如何实现它?

持久化布尔逻辑

我会将OrQualificationsAndQualifications存储为单独的实体,并将它们与Job实体保持多对多引用,这样您就可以区分资格。

要查看申请人是否具有正确的资格,您需要检查AndQualification实体中的所有资格都满足,并且OrQualifications实体中的任何资格都满足。


编辑:

上面/最初的答案是为了满足一个必要的资格列表的要求,另一个至少需要一个。对我来说,这似乎已经足够好了,您确定您真的需要嵌套的限定条件吗?相信我,让一个应用程序比它需要的更复杂是一个坏主意。

表达式树
嵌套限定条件是另一个问题,这里有一个建议的解决方案:将表达式存储为完整二叉树(每个节点恰好有0或2个子节点的二叉树)。该树中的所有节点由AND或or (&或|)除了叶子,这将是资格。


示例表达式:(A | B &;C) | D &;E)

(从表达式到树的转换完全取决于输入数据的方式,最简单的方法是手动创建树!)

作为树:

<>之前|/'| &/'/'A & d e/'B C之前

关于如何将此树持久化到数据库中,您有许多不同的选择,例如:

  • 绝对最小值为两列的层次模型,一个Id和一个ParentId。要获取树,需要递归查询。对于关系数据库来说,这个选项可能要求很高。
  • 序列化树为xml (XmlSerializer)或json (json.NET),并保存为文本。

我个人会选择序列化选项,因为你总是需要完整的树,它很容易反序列化成一个数据结构。

下面是一个示例数据结构:

public class Node
{
    public Node LeftChild { get; set; }
    public Node RightChild { get; set; }
}
class OperatorNode : Node
{
    public bool IsAnd { get; set; }
}
class QualificationNode : Node
{
    public bool IsQualificationMet { get; set; }
}

那么你需要一个函数来解析这个树并输出真或假:

public bool EvaluateNode( Node node )
{
    var qualificationNode = node as QualificationNode;
    if ( qualificationNode != null )
    {
        return qualificationNode.IsQualificationMet;
    }
    var operatorNode = node as OperatorNode;
    if ( operatorNode.IsAnd )
    {
        return EvaluateNode( node.LeftChild ) && EvaluateNode( node.RightChild );
    }
    return EvaluateNode( node.LeftChild ) || EvaluateNode( node.RightChild );
}

免责声明:这是所谓的快速和肮脏的代码,请做一些更好的

其他选择
查看System.Linq.Expressions.Expression。它可以用于以编程方式构建逻辑,所以也许这是您可以使用的东西。