2

我们正在将遗留系统移植到 .NET,既是为了清理架构,也是为了利用许多在遗留系统中不容易实现的新可能性。

注意:在提交之前阅读我的帖子时,我注意到我可能在某些地方描述得太快了,即。掩盖了细节。如果有任何不清楚的地方,请发表评论(不是答案),我会尽可能多地补充

遗留系统使用数据库和 100% 自定义编写的 SQL。这导致了宽表(即许多列),因为需要数据的代码只检索工作所需的内容。

作为移植的一部分,除了自定义 SQL 之外,我们还引入了一个我们可以使用的 ORM 层。我们选择的 ORM 是 DevExpress XPO,其中一个特性也给我们带来了一些问题,即当我们为 Employee 表定义 ORM 类时,我们必须为所有列添加属性,否则它不会为我们检索它们。

这也意味着当我们检索一个 Employee 时,我们会得到所有的列,即使我们只需要一些列。

拥有 ORM 的一个好处是我们可以将一些与属性相关的逻辑放入相同的类中,而不必到处复制它。例如,将名字、中间名和姓氏组合成“显示名称”的简单表达式可以放在那里,作为示例。

但是,如果我们在某处编写 SQL 代码,无论是在类似 DAL 的构造中,还是在任何地方,我们都需要复制这个表达式。这感觉不对,看起来像是错误和维护噩梦的秘诀。

但是,由于我们有两个选择:

  • ORM,获取所有内容,可以编写一次逻辑
  • SQL,获取我们需要的,需要复制逻辑

然后我们想出了一个替代方案。由于 ORM 对象是从字典代码生成的,我们决定也生成一组哑类。这些将具有相同数量的属性,但不会以相同的方式绑定到 ORM。此外,我们为所有对象添加了接口,也生成了,并使 ORM 和 dum 对象都实现了这个接口。

这使我们能够将其中的一些逻辑移出到与接口相关的扩展方法中。由于哑对象携带了足够的信息让我们将它们插入到我们的 SQL 类中,而不是返回 DataTable,我们可以返回一个 List,并提供可用的逻辑,这看起来是可行的。

然而,这导致了另一个问题。如果我想编写一段代码,仅在我需要知道他们是谁(即他们在系统中的标识符)以及他们的姓名(名字、中间名和姓氏)的上下文中显示或处理员工,如果我使用这个愚蠢的对象,编译器无法保证调用我的代码确实提供了所有这些东西。

一种解决方案是让我们让对象知道哪些属性已被赋值,并且尝试读取未赋值的属性会因异常而崩溃。这使我们有机会在运行时发现代码未传递足够信息的合同违约。

这对我们来说也很笨拙。

所以基本上我想要的建议是是否有其他人曾经或正在这种情况下,以及您可以提供的任何提示或建议。

目前,我们不能拆散桌子。由于端口的大小,旧应用程序仍需存在数年,并且 .NET 代码不是 3 年内发布类型的项目,但将在此过程中逐步发布。因此,遗留系统和 .NET 代码都需要使用相同的表。

我们也知道这不是一个理想的解决方案,所以请不要提出“你不应该这样做”这样的建议。我们很清楚这一点:)


我们研究过的一件事是使用“合同”创建一个 XML 文件或类似文件。所以我们可以在这个 XML 文件中加入如下内容:

  • 有一个 Employee 类具有这 50 个属性
  • 此外,对于程序的各个部分,我们有这 7 种变体
  • 此外,我们有这 10 条逻辑,每条都需要属性 X、Y 和 Z(X、Y 和 Z 在这 10 种之间变化)

这可以让我们对这 8 个类(全类 + 7 个较小的变体)进行代码生成,并让生成器检测到变体 #3 的属性 X、Y 和 K 是否存在,然后我可以将代码绑定到逻辑或逻辑需要自动进入此类的接口。这将允许我们拥有许多不同类型的员工类,具有不同程度的属性覆盖,并让生成器自动将此类支持的所有逻辑添加到它。

然后我的代码可以说我需要一个 IEmployeeWithAddressAndPhoneNumbers 类型的员工。

这看起来也很笨重。

4

3 回答 3

3

我建议最终可能需要进行数据库重构(规范化)。您可以进行重构并使用视图来为遗留应用程序提供与数据库的接口与其期望一致的接口。也就是说,例如,将员工表分解为employee_info、employee_contact_info、employee_assignments,然后为遗留应用程序提供一个名为employee 的视图,该视图在这三个表之间进行连接(或者如果逻辑是基于表的函数更复杂)。这可能会让您继续使用完全基于 ORM 的解决方案,这是我更喜欢的解决方案,并让您的遗留应用程序满意。我不会继续使用 ORM/直接 SQL 的混合解决方案,

于 2008-11-16T12:51:24.617 回答
2

“目前,我们无法拆分表格。由于端口的大小,旧应用程序仍将存在数年,而 .NET 代码不是 3 年内——发布类型的项目,但将在发布过程中逐步加入。因此,遗留系统和 .NET 代码都需要使用相同的表。

两个字:物化的观点。

您有几种“就地标准化”的方法。

  1. 物化视图,a/k/a 索引视图。这是源表的规范化克隆。

  2. 从旧表显式复制到新表。“我”你说。但是,请考虑您将逐步从旧应用程序中删除功能。这意味着您将在新的规范化表中拥有一些功能,并且可以优雅地忽略旧表。

  3. 显式 2 路同步。这很难,并非不可能。您通过从旧表复制到正确设计的表进行规范化。作为临时解决方案,您可以使用存储过程和触发器将事务克隆到遗留表中。然后,随着转换的进行,您可以淘汰这些杂物。

在两个完全不同的模式中执行此操作会很高兴。由于旧数据库可能没有设计良好的模式,因此您的新数据库将具有一个或多个命名模式,以便您可以对定义进行一些版本控制。

于 2008-11-16T13:13:42.420 回答
0

尽管我没有使用过这种特殊的 ORM,但视图在某些情况下可以用于为这些类型的数据库中的显示和报告提供更轻量级的对象。根据他们的文档,他们确实支持这样一个概念:XPView Concepts

于 2008-11-16T13:47:40.340 回答