c# - 需求变更 : Use database table instead of enums. 如何处理使用枚举值的现有记录?

标签 c# sql-server database tsql enums

所以要求(实际上是法律)已经改变,客户希望能够从当前的枚举中添加/删除值。所以我需要创建一个数据库表,以允许客户端在运行时动态处理值列表。

目前我的数据库中有一个名为 tblJob 的表,该表有一个类型为 int 的列 PaymentTypes 对应于枚举已经用过。因此,每次在系统中创建一个新作业时,用户都会从这个枚举列表中选择一个 PaymentType,并将其作为新记录存储在 tblJob

为了应对新需求,我添加了一个新表tblPaymentTypes,并将当前枚举列表硬编码到表中。这里的每个值都有一个唯一的 GUID 标识符。这一切都很好。

现在,对于每个新工作,从数据库中检索 PaymentType 选项,然后用户选择一个。但是,我需要更改表 tblJobPaymentTypes 列的 type 以允许使用 GUID 值的整数。

我可以这样做,但是所有具有整数值作为 PaymentType 的现有记录怎么办?

来自 MSDN 关于使用现有数据修改列类型:

Modifying the data type of a column that already contains data can result in the permanent loss of data when the existing data is converted to the new type. In addition, code and applications that depend on the modified column may fail. These include queries, views, stored procedures, user-defined functions, and client applications. Note that these failures will cascade. For example, a stored procedure that calls a user-defined function that depends on the modified column may fail. Carefully consider any changes you want to make to a column before making it.

这很有道理。

为了避免这个问题过于局限,这些是我要问的一般问题:

  • 更改列类型时如何处理现有记录?我是否必须编写一个一次性脚本,将当前值映射到新的 GUID 值。
  • 在这种情况下,使用数据库表来代替枚举是否是正确的选择? C# 中有动态枚举的概念吗?

感谢任何帮助/指点。

最佳答案

为什么标识符需要是 GUID?如果查找表只使用整数标识符(大多数表通常这样做),那么该表中的初始记录数量可以与枚举的整数值完全一致。然后不需要数据迁移,只需将外键关系从tblJob添加到tblPaymentTypes即可。

如果您必须使用 GUID(尽管我仍然认为您不应该这样做,如果没有其他原因,只是因为它们会产生糟糕的聚集索引),那么您将有一个数据迁移过程,它可能包括以下步骤:

  1. 添加 tblPaymentTypes 表和数据。
  2. tblJob 添加一个 GUID 列,可为空,无外键。
  3. 更新 tblJob 以将新列的每个值设置为枚举中的相应值(可能是硬编码映射,因为它是一次性脚本)。
  4. 使新列不可为空,并为 tblPaymentTypes 设置外键。
  5. tblJob 中删除包含整数枚举值的列。
  6. 更新使用代码以使用新列而不是旧列。

如果提前计划和编写脚本,实际上执行这些步骤应该会非常快,在此过程中您可能只有一两分钟的停机时间。 (在像这样迁移数据时,您会希望将数据库与应用程序隔离开,以避免迁移过程中的任何状态更改造成任何类型的数据损坏。)但是您可以看到这将是一个很多使用您已有的相同数据类型更容易。

关于c# - 需求变更 : Use database table instead of enums. 如何处理使用枚举值的现有记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27658647/

相关文章:

c# - 如果值匹配多个键,则从字典中删除所有键

c# - 如何将 System.Type 转换为其可为 null 的版本?

c# - .NET SMTP 邮件 - 错误 = helo 命令被拒绝需要完全限定的主机名

python - 如何将字典/列表存储在数据库中?

database - 无法启动 mySQL 服务器 Windows 8

c# - 从 C# 调用默认浏览器?

sql-server - 这是 LEAD() IGNORE NULLS 的错误吗?

sql - 确定服务器产品版本并相应地执行 SQL 的最佳方法?

SQL选择日期范围的第一个值和最后一个值

c++ - 数据库。错误 C2352 : illegal call of non-static member function