持久化布尔逻辑

3

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

我有以下需求: 我想从表格中保存特定工作实体(不要与SQL Server作业混淆)的资格要求到SQL Server 2012中。 为此,我有另一个表,称为“资格要求”,它将上述资格要求保存在具有参考完整性的工作表中。 制作此存储过程的参数为JobID和用户定义的模式表类型。

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

我在业务层有对应的实体。 当用户为工作创建多个资格时,他将列表传递给函数,底层方法将列表转换为数据表,并使用存储过程添加到数据库中。
问题在于资格可以是OR或AND。 例如,如果有5个资格,如 qualification1 qualification2 qualification3 qualification4 qualification5
并且强制应用于工作,
qualification1 OR qualification2 OR qualification3 AND qualification4 AND qualification5
所以它使三个组
(qualification1 OR qualification2 OR qualification3) AND (qualification4) AND (qualification5)
那么我该如何在QualificationEntity类和Database中解释它呢? 我正在使用ADO.NET调用SP,通过手动将列表转换为用户定义的表类型的DataTable,如何实现它?

1
你想要实现什么目标?你只是想将资格存储在数据库中,还是想验证完整性? - Brian P
一旦我将其存储在数据库中并保持关系,我将使用相同的结构进行验证。 - MaxRecursion
你最终采用了哪种方法,它的效果如何?我也需要在项目中做到这一点。 - Jon Seigel
1个回答

3
我会将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。 它可以用于以编程方式构建逻辑,因此这可能是您可以使用的内容。


但是ORQualifications会形成一个组并且可以嵌套,而且这个组应该被满足,那么我如何追踪哪个资格证书是Or的,以及它属于哪个组? - MaxRecursion
@AkshayKulkarni 嵌套资格意味着表达式树,这更加复杂,请查看我的更新答案。 - Andreas Ågren
@AkshayKulkarni 这是你在寻找的吗? - Andreas Ågren
不完全是,但我采用了设计方法。谢谢你的帮助。 - MaxRecursion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接