3

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

我有如下要求:我想从表中保存 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 传递给函数,并且底层方法将列表转换为数据表并使用存储过程添加到数据库中。

问题是 OR 或 AND 中的限定条件。例如,如果有 5 个资格,则说资格 1 资格 2 资格 3 资格 4 资格 5

并被强制执行为

资格 1 或资格 2 或 资格 3 和资格 4 和资格 5

所以它制作了三组

(资格 1 或资格 2 或资格 3)与(资格 4)与(资格 5)

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

4

1 回答 1

3

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

要确定申请人是否具有正确的资格,您检查是否满足实体中的所有资格,以及AndQualification是否满足实体中的任何资格OrQualifications


编辑:

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

表达式树
嵌套限定是另一种野兽,这里是一个建议的解决方案:表达式存储为完整的二叉树(每个节点正好有 0 或 2 个子节点的二叉树)。这棵树中的所有节点都由运算符 AND 或 OR(& 或 |)组成,除了作为限定条件的叶子。

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

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

作为一棵树:

      |
   / \
  | &
 / \ / \
A&DE
   / \
  公元前

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

  • 绝对最小值为两列的分层模型,一列 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。它可用于以编程方式构建逻辑,因此也许这是您可以使用的东西。

于 2013-01-08T12:37:32.173 回答