2

在我正在开发的新系统中,我正在切换到更面向对象的ASP.NET Web 应用程序方法。

我有一个大多数人都会熟悉的通用结构。我有一个有多个部门的学校结构;属于一个部门的课程;和属于多个课程的学生。

在部门视图中,我列出了属于该部门的所有课程,并且我想要每门课程的汇总数据,例如入学人数、退学人数、男性/女性人数等。

然而,在个人课程视图中,我需要学生的实际列表以及他们的详细信息,例如他们是否注册、通过课程、性别等。

然后是单个学生视图,其中显示有关学生的所有详细信息,包括其他课程的注册、地址等。

以前,我会有一个数据访问层返回我在每种情况下需要的任何数据,并将其作为SQLDataReader或返回DataSet(在 VB.NET 中工作)。现在,我正在尝试以面向对象的方法对此进行建模,我在DAL中创建对象并将这些对象返回到BLL。当我需要对象中的聚合详细信息时,我不确定如何处理这个问题。例如,在带有课程列表的部门视图中,我将汇总每个课程。我会在那些轻量级课程对象存储聚合值的部门中存储一些轻量级课程对象的集合吗?

我想在不同的场景中需要不同级别的抽象,我不确定处理这个问题的最佳方法。我是否应该有一个对象模型,其中有一个存储聚合的非常基本的课程对象,以及一个存储完整细节的子对象?

另外,如果有任何有用的资源可以帮助我理解如何为这些东西建模,那就太好了。

4

4 回答 4

4

不要把事情复杂化,不要做不必要的工作。数据库在数据操作方面是完美的,所以让数据库来做聚合。在代码方面,再向您的对象模型添加一个对象,您就可以了:

class CourseStats
    string Name { get; }
    int Enrollments { get; }
    int Withdrawals { get; }

进行聚合的 SQL 非常简单。但是,请务必使用 ORM(想想NHibernate)或不太复杂的 Result-Set Mapper (想想BLToolkit):您真的不想手动水合这些对象。

另一个好处是您可以缓存两个查询结果(一旦与课程相关的内容发生更改,缓存就会失效)。

于 2009-10-08T09:08:34.253 回答
1

这实际上是许多人都在努力解决的一个相当大的问题。

据我所知,在这个问题上至少有两种思想流派:

  • 具有支持延迟加载的 OR/M 的持久无知域对象
  • 领域驱动设计和显式建模(和显式加载)聚合

Jeremy Miller在 MSDN 杂志上有一篇文章调查了一些持久性模式。

Domain-Driven Design一书对建模聚合进行了很好的讨论。

于 2009-10-08T09:10:36.503 回答
0

如果部门很少,每个部门的课程数量也很少,那么只需加载所有内容并让您的对象进行数学运算(即部门迭代课程列表并总结您需要的内容)。

另一种方法是使用一些自定义的本机 SQL 对数据库运行总和。您可以将其隐藏在 DAL 中。然后,DAL 将返回,例如,虚拟课程(数据库中不存在但包含总和)。

第三种方法是将这些值保存在部门对象中的某个位置,并在每次更改/添加/删除课程时更新它们。

于 2009-10-08T09:09:05.197 回答
0

如果您使用 .NET,您应该调查的一件事是LINQ to SQL。它将允许您在 DAL 中拥有一个非常优雅的界面。LINQ 将允许您在 BLL 中制作聚合查询,从而节省管道代码以及遍布整个源代码的讨厌的 SQL 片段。上一个使用 LINQ 表示的聚合 SQL 查询链接的示例:

var averageOrderTotals =
  customers.
  Select(c => new {
      c.Name,
      AverageOrderTotal = c.Orders.Average(o => o.Total)
   });

我已经将我的数据库层切换到了 LINQ,尽管在我的情况下我不使用 MS SQL Server,所以我使用了DbLinq库。

您要做的最后一件事是必须修改您的类以适应您的数据库访问层,这样做会使您的解决方案非常脆弱。

于 2009-10-08T09:21:27.770 回答