我在这里寻找指针和信息,我会制作这个 CW,因为我怀疑它没有一个正确的答案。这是针对 C# 的,因此我将在下面对 Linq 进行一些引用。我也为这篇长文道歉。让我在这里总结一下问题,然后是完整的问题。
总结:在 UI/BLL/DAL/DB 4 层应用程序中,如何更改用户界面,显示更多列(例如在网格中),避免通过业务逻辑层泄漏到数据访问层,以获取要显示的数据(假设它已经在数据库中)。
让我们假设一个具有 3(4) 层的分层应用程序:
- 用户界面 (UI)
- 业务逻辑层 (BLL)
- 数据访问层 (DAL)
- 数据库(DB;第 4 层)
在这种情况下,DAL 负责构造 SQL 语句并针对数据库执行它们,返回数据。
是“正确”构建这样一个层以始终执行“选择*”的唯一方法吗?对我来说,这是一个很大的禁忌,但让我解释一下为什么我想知道。
假设我希望在我的 UI 中显示所有拥有有效就业记录的员工。“活动”是指就业记录从开始到日期包含今天(或者甚至可能是我可以在用户界面中设置的日期)。
在这种情况下,假设我想向所有这些人发送电子邮件,所以我在 BLL 中有一些代码可以确保我还没有向同一个人发送电子邮件,等等。
对于 BLL,它需要最少的数据量。也许它会调用数据访问层来获取活跃员工的列表,然后调用来获取它已发送的电子邮件列表。然后它加入这些并构造一个新列表。也许这可以在数据访问层的帮助下完成,这并不重要。
重要的是,对于业务层来说,它需要的数据真的不多。也许它只需要两个列表的每个员工的唯一标识符进行匹配,然后说“这些是那些活跃的人的唯一标识符,你还没有发送过电子邮件”。然后我是否构建 DAL 代码来构建仅检索业务层需要的 SQL 语句?IE。只是“从员工那里选择 id ...”?
那么我该怎么做用户界面呢?对于用户而言,最好包含更多信息,具体取决于我要发送电子邮件的原因。例如,我可能想包括一些基本的联系信息,或者他们工作的部门,或者他们的经理姓名等,而不是说我至少要显示姓名和电子邮件地址信息。
UI 如何获取这些数据?我是否更改 DAL 以确保将足够的数据返回给 UI?我是否更改 BLL 以确保它为 UI 返回足够的数据?如果从 DAL 返回到 BLL 的对象或数据结构也可以发送到 UI,那么 BLL 可能不需要太多更改,但是 UI 的要求会影响层超出它应该与之通信的层. 如果这两个世界在不同的数据结构上运行,则可能必须对两者进行更改。
那么当 UI 发生变化时,为了进一步帮助用户,通过添加更多列,我必须/应该多深才能更改 UI?(假设数据已经存在于数据库中,因此不需要更改。)
提出的一个建议是使用 Linq-To-SQL 和 IQueryable,这样如果处理什么(如在什么类型的数据中)和为什么(如在 WHERE 子句中)返回 IQueryables 的 DAL,BLL 可以可能会将这些返回到 UI,然后 UI 可以构造一个 Linq 查询来检索它需要的数据。然后,用户界面代码可以拉入它需要的列。这会起作用,因为使用 IQuerables,UI 最终会实际执行查询,然后它可以使用“select new { X, Y, Z }”来指定它需要什么,甚至在必要时加入其他表。
这对我来说看起来很乱。UI 自己执行 SQL 代码,即使它隐藏在 Linq 前端之后。
但是,为了发生这种情况,不应该允许 BLL 或 DAL 关闭数据库连接,并且在 IoC 类型的世界中,DAL 服务可能会比 UI 代码想要的更快地被处理掉,所以Linq 查询可能只是以“无法访问已处置的对象”异常结束。
所以我正在寻找指针。我们离我们有多远?你是如何处理这个问题的?我认为对 UI 的更改会通过 BLL 泄漏到 DAL 中的事实是一个非常糟糕的解决方案,但现在看起来我们无法做得更好。
请告诉我我们有多愚蠢并证明我错了?
请注意,这是一个遗留系统。多年来,更改数据库架构并不在范围内,因此使用 ORM 对象的解决方案基本上相当于“选择 *”并不是一个真正的选择。我们有一些大表,我们希望避免拉起整个层列表。