在哪里放置业务逻辑?在 VB.Net?或者在 SQL?

Where to put Business Logic? In VB.Net? Or in SQL?

我正在创建一个允许我创建计划任务的应用程序。我有一个线程进程,每分钟 运行s 在后台运行,并触发以下 class:

Namespace MyName.space
  Public Class RunJob
  ...
  End Class
End Namespace

作业可以是 "Run Once" 或 "Recurring"。

我正在查询 vb.net 中的作业 table,将结果存储在数据集中,以便我可以一次对它们进行迭代。然后我开始考虑根据作业的独特标准来验证作业是否应该 运行 的函数。

例如,最简单的是 "Run Once" 个职位:

If Type = "Run Once"
    JobShouldRun = Helpers.Validate_RunOnce(WhenToRun, RunCount)
ElseIf Type = "Recurring"
    ...
End If

该函数将检查 "WhenToRun" 是否在服务器上配置的当前日期和时间的 5 分钟内。我选择了 5 分钟 window 以防任务失败,这样一分钟后它会重试并且还剩下 3-4 次尝试。

但后来我开始考虑我可以在 SQL 查询中控制更多内容以自己获取作业,并跳过在 vb.net 中验证此 "easy",但我我不确定哪种方法更理想。所以我可以限制结果集在我的初始查询中开始:

SELECT
     JobId
    ,JobType -- Run Once or Recurring
    ,WhenToRun

FROM JobTable a
WHERE Active = 1
AND (
      JobType = 'Run Once'
      AND TotalRuns = 0
      AND DATEDIFF(minute, getdate(), a.WhenToRun) BETWEEN 1 AND 5
    )
OR JobType = 'Recurring'

然后我开始思考,我是否应该使用 UNION 或 JOINS 执行我的所有逻辑,或者对重复作业执行复杂的 WHERE/AND/OR 条件?他们变得相当复杂......例如每周和一周中的哪几天,什么时间等。或者在每月的最后一天 "Jan|March|Etc" 中每 "int" 年。

所以我开始沿着这些思路思考:

SELECT 
     JobID
    ,JobType
    ...
FROM JobTable 
WHERE RecurringType = 'Weekly'
AND ... more conditions based on all the custom job settings

UNION ALL

SELECT
     JobID
    ,...
FROM JobTable 
WHERE RecurringType = 'Monthly'
AND ... more conditions based on all the custom job settings

这个查询最终会变得非常庞大和复杂,但我的问题是,我应该在 vb.net 或 SQL 中处理这个问题,还是 SQL 中的简单内容等等vb.net 中的复杂条件?我不确定这两个方向对性能的影响。

您基本上是在问 "Where do I put code for business logic? In the app? Or in the database?" 这可能是一个争论不休的话题,但考虑两种选择是明智的。每种方法都有一些权衡,说一种方法是正确的而另一种方法是错误的似乎有点武断。

如果您的 BL 代码在应用程序中,您将获得 .Net Framework 的健壮性的主要好处。我喜欢 tsql,但你不能用它做尽可能多的事情 VB.Net。如果我能对开发人员形成刻板印象,我怀疑他们通常会更喜欢 .Net 代码。对于大多数人来说,它可能比 tsql 更容易调试。由于 .Net 代码被编译为程序集,因此也不太可能被更改。

如果你的BL代码在tsql中,你可能会发现性能会好一点。您还从 .Net 代码中抽象出一些复杂性,并使该代码库更小一些(有些人可能认为这是一件坏事)。如果存在需要修复的错误,重新部署存储过程(或用户定义的函数、视图等)通常比重新部署应用程序(尤其是涉及多个工作站时)更容易。不利的一面是,其他人很容易看到(窃取!)您的代码或对其进行更改。

一般来说,业务逻辑越复杂,我就越有可能将其放入应用程序中。如果它非常简单并且不太可能改变,我会考虑将它放在 tsql 中。话虽这么说,如果我必须毫无例外地选择一个或另一个,我会把 BL 放在应用程序中。