如何为将来可能会更改的数据库表设计数据访问层

本文关键字:数据库 数据 访问 将来 | 更新日期: 2023-09-27 18:08:48

简介:

在我目前的实习中,我正在重构(几乎重写(一个遗留的应用程序。这个问题将关注的部分是它使用的数据库以及他们从中检索数据的方式。

数据库结构为:

  1. 有一个包含主要记录的表。假设每条记录都是一个度量值。它有一些关于测量材料和不同测量信息的信息。
  2. 他们使用的一个表视图具有相同的信息列,以及一些额外的列,其中包含根据给定测量值计算的数据。它还会过滤表中的一些数据。

因此,假设我们有包含列的主表:

Measurement ID
Measurement A
Measurement B

该视图如下所示:

Measurement ID
Measurement A
Measurement B
Some extra data (for example Measurement A * Measurement B)

领导开发的人只知道一些SQL,所以他喜欢添加新列,这些列是由主表中的某些列计算的,用于试验。这绝对是目前的需求

要求是:

  1. 应该支持不同类型的数据库(如SQL Server,Oracle,可能还有其他一些数据库(。
  2. 前端应该能够显示视图,这意味着即使某些主列将始终保持不变,也可能有一些新列,包括新计算的值。

我的问题是:

我应该使用哪种系统来满足此应用程序的需求?我想使用实体框架,但我认为该视图将来可能会有新列这一事实是一个问题。据我了解,我应该在编译之前将我的类映射到数据库。

我正在考虑的另一件事可能是使用实体框架从主表中获取数据,并直接在前端执行当前在表视图中完成的计算和筛选,并完全跳过视图。这听起来不错,虽然我不知道他们是否允许我这样做。

在我的情况下,你会怎么做?请注意,我对数据库和ORM几乎没有经验。

如何为将来可能会更改的数据库表设计数据访问层

是正确的,如果基础数据库架构始终在更改,则使用实体框架将是一个问题。它将要求您每次更新 EF 模型以抓取这些新列。

理想情况下,您的所有数据库访问都隐藏在DAL接口后面,因此您的应用程序不需要知道正在使用哪个ORM - 如果有的话 - 或者它连接到哪个数据库。

我不想这么说,但考虑到您的要求,ORM 可能没有意义。您可能希望使用更通用的东西,而无需任何强类型。您只需始终将 DataTable 返回到应用程序层,它就可以遍历列和值以显示返回的任何内容。如果您知道有些字段永远不会更改,则可以仅为这些字段创建到应用程序对象的手动映射。

你可以看看NoSQL系统,它在模式上要灵活得多。或者看看像RavenDB这样的文档数据库。所有这些系统都允许架构动态更改。您需要检查优点和缺点,看看它是否可以满足您的要求。

(这个答案有点偏离主题,因为它是关于替换SQL服务器而不是真正创建DAL,但其他答案很好地涵盖了这个主题,我想提出另一种可能有帮助的方法。

如果您的架构不稳定,那么作为初学者使用实体框架将是一个令人头疼的问题。假设您可以定期刷新设计画布,让该工具处理数据库表更改。您可以尝试一段时间,看看什么时候变得太痛苦了,但是没有任何使用ORM或实体框架的经验,这可能不值得付出努力。

我可能会使用像Rob Conery的Massive ORM(https://github.com/robconery/massive(这样的东西。它为您提供了更大的基础数据库架构灵活性,并且是一个非常小的库。我记得它是~300行代码,非常易于使用。它使用 C# 动态,因此您必须使用>= C# 4.0 并熟悉这个概念,但 IMO 对于低开销来说是值得的。像Entity Framework或NHibernate这样的成熟的ORM将花费大量的学习周期。

当然,你可以坚持使用 ADO.NET 数据表。他们有点丑陋和冗长,但他们会完成这项工作。

如果数据库正在更改,则可以使用实体框架 - 数据库优先。当然,当您希望能够访问新列时,当数据库架构更改时,您必须重新生成类。

如果需要容纳不同的数据库服务器,则应考虑实现存储库模式,并以这种方式抽象所有数据访问。

您的评论

它涉及对主表的写入操作,但主表永远不会更改

证实了我的希望。这意味着您可以使用实体框架作为应用程序的核心,并使用不同的路由来显示数据。

假设对于显示(视图(,您使用经典DataTable(因为所有常见网格都支持它们,而不是显示动态对象(。我不知道如何创建/更新/删除,但保存更改在某些时候会涉及将DataRow映射到MainEntity对象。您可以为此编写一种方法,例如

MainEntity DataRowToEntity(DataRow row)
{
    var entity = new MainEntity();
    entity.PropertyA = row["PropertyA"];
    ....
}

MainEntity可以附加到上下文,其状态更改为 Modified ,然后保存。