c# - 持久化 bool 逻辑

标签 c# sql sql-server ado.net boolean-logic

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

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

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

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

要注意的是条件可以在 OR 或 AND 中。 例如,如果有 5 个资格说 资质1 资格2 资质3 资质4 资质5

并强制执行

qualification1 OR qualification2 OR qualification3 AND qualification4 AND qualification5

所以它分为三个组

(qualification1 OR qualification2 OR qualification3) AND (qualification4) AND (qualification5)

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

最佳答案

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

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


编辑:

上述/初始答案是为了满足一份所需资格 list 的要求,以及至少需要一份资格 list 的另一份 list 的要求。对我来说这似乎足够好了,你确定你真的需要嵌套资格吗?相信我,让应用程序变得比它需要的更复杂是个坏主意。

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

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

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

作为一棵树:

      |
   /     \
  |       &
 / \     / \
A   &   D   E
   / \
  B   C

You have a number of different choices on how to persist this tree to a database, e.g:

  • A hierarchial model where the absolut minimum is two columns, one Id and one ParentId. To fetch the tree you need a recursive query. This option can be pretty demanding for a relational database.
  • Serialize the tree as e.g. xml (XmlSerializer) or json (json.NET) and save it as text.

Personally I would choose the serializing option as you will always need full trees and it's easy to deserialize into a datastructure.

Here is an example datastructure:

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

关于c# - 持久化 bool 逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14214436/

相关文章:

c# - 使用按钮单击 c# 在列表框中选择多个项目

sql-server - 在 SQL 2000 中打开一个 .BAS DTS 包?

c# - 使用控制台应用程序 .NET Core 在 C# 中并行运行两个 dotnet 进程

sql - 整数字段中的 NULL 与 0

mysql - 如何在 SQL 中对 `describe ` 语句的结果进行排序?

mysql - 如何在数据集中生成值

sql - 读取 JSON 数组作为 SQL 表列之一

sql - sql server中!=和<>有什么区别

C# 将部分字符串视为 var

c# - 将 RTF 编辑为纯文本但无法再次打开