不使用ORM的N层数据库应用程序,UI如何指定数据显示的内容?

ang*_*son 6 c# business-logic data-access-layer isolation leaky-abstraction

我在这里寻找指针和信息,我会做这个CW,因为我怀疑它没有一个正确答案.这是针对C#的,因此我将在下面对Linq进行一些引用.我也为这篇长篇大论道歉.让我在这里总结一下这个问题,然后是完整的问题.

简介:在UI/BLL/DAL/DB 4层应用程序中,如何更改用户界面,以显示更多列(例如在网格中),避免泄漏通过业务逻辑层进入数据访问层,掌握要显示的数据(假设它已经在数据库中).


让我们假设一个有3(4)层的分层应用程序:

  • 用户界面(UI)
  • 业务逻辑层(BLL)
  • 数据访问层(DAL)
  • 数据库(DB;第4层)

在这种情况下,DAL负责构造SQL语句并对数据库执行它们,返回数据.

"正确"构建这样一个层的唯一方法就是总是"select*"吗?对我来说这是一个很大的禁忌,但让我解释为什么我在想.

让我们说,对于我的用户界面,我希望显示所有拥有活跃就业记录的员工."活跃"是指今天的就业记录包含今天(或者甚至是我可以在用户界面中设定的日期).

在这种情况下,假设我想向所有这些人发送一封电子邮件,因此我在BLL中有一些代码可以确保我还没有向同一个人发送过电子邮件,等等.

对于BLL,它需要最少量的数据.也许它调用数据访问层来获取活动员工列表,然后调用以获取它发送的电子邮件列表.然后它加入这些并构造一个新列表.也许这可以在数据访问层的帮助下完成,这并不重要.

重要的是,对于业务层,它实际上并不需要太多数据.也许它只需要每个员工的唯一标识符,对于两个列表,匹配,然后说"这些是活动的那些的唯一标识符,您还没有发送电子邮件到".然后构建DAL代码,构造只检索业务层需要的SQL语句吗?IE浏览器.只是"SELECT id FROM employees WHERE ..."?

那么我该怎么做用户界面呢?对于用户来说,这或许会是最好的,包括了很多信息,这取决于为什么我要发送电子邮件.例如,我可能想要包括一些基本的联系信息,或者他们工作的部门,或者他们的经理姓名等,而不是说我至少要显示姓名和电子邮件地址信息.

用户界面如何获取数据?我是否更改了DAL以确保将足够的数据返回给UI?我是否更改BLL以确保它为UI返回足够的数据?如果从DAL返回到BLL的对象或数据结构也可以发送到UI,那么BLL可能不需要进行太多的更改,但是UI的要求会影响超出应该与之通信的层. .如果这两个世界在不同的数据结构上运行,则可能必须对两者进行更改.

那么当UI被更改时,为了进一步帮助用户,通过添加更多列,我需要多深才能更改UI?(假设数据已存在于数据库中,因此不需要进行任何更改.)

提出的一个建议是使用Linq-To-SQL和IQueryable,这样如果DAL处理什么(如在什么类型的数据中)和为什么(如WHERE-clauses中)返回IQueryables,那么BLL可以可能会将这些内容返回到UI,然后可以构建一个Linq查询来检索所需的数据.然后,用户界面代码可以拉入所需的列.这将有效,因为使用IQuerables,UI最终会实际执行查询,然后它可以使用"select new {X,Y,Z}"来指定它需要的内容,甚至可以在必要时加入其他表.

这看起来很混乱.UI执行SQL代码本身,即使它已隐藏在Linq前端后面.

但是,为了实现这一点,不应该允许BLL或DAL关闭数据库连接,并且在IoC类型的世界中,DAL服务可能比UI代码所希望的更快地被处理掉,因此Linq查询可能最终会出现"无法访问已处置对象"的异常.

所以我正在寻找指针.我们有多远?你是怎么处理的?我认为UI的更改将通过BLL泄漏到DAL中是一个非常糟糕的解决方案,但是现在它看起来并不像我们能做得更好.

请告诉我我们有多愚蠢并证明我错了?

请注意,这是一个遗留系统.多年来,更改数据库模式的范围还不在范围内,因此使用ORM对象的解决方案基本上与"select*"相当,实际上并不是一种选择.我们有一些大型表格,我们希望避免在整个图层列表中提取.

Pre*_*gha 1

使用作为 UI 消费案例的视图模型(或数据传输对象)的概念。BLL 的工作就是获取这些对象,如果数据不完整,则请求附加数据(我们称之为模型)。然后 BLL 可以就返回哪些视图模型做出正确的决定。不要让您的模型(数据)细节渗透到 UI 中。

UI <-- (viewmodel) ---> BLL <-- (model) --> Peristence/Data layers
Run Code Online (Sandbox Code Playgroud)

这种解耦可以更好地扩展您的应用程序。我认为持久性独立性很自然地从这种方法中消失,因为视图模型的构造和规范可以通过使用 linq2ql 或其他 orm 技术在 BLL 中灵活完成。