我会将OrQualifications
and存储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。它可用于以编程方式构建逻辑,因此也许这是您可以使用的东西。