【问题标题】:Is using an id as a business value an anti-pattern [closed]使用 id 作为商业价值是一种反模式[关闭]
【发布时间】:2017-07-26 09:32:32
【问题描述】:

冒着被贴上题外话的风险,我会问它任何方式:-)

我最近加入了一个新的开发团队,他们确实有执行以下操作的习惯。虽然我一直认为它是一种反模式,但我发现我无法解释为什么。所以,我只是想听听您的意见。

让我们考虑以下情况:您有一个发票应用程序,当需要创建新发票时,它必须获取一个新的唯一发票编号(如 INV0001)。当然,它将存储在数据库中,在具有自动增量字段“id”的表中。因此,只需从 id 生成 Number。

class Invoice{
     [Key]
     int Id { get; set;}

     string Number => String.Concat("INV", this.Id.ToString().PadLeft(4, '0'));
}

我一直(盲目地)遵守“不要将 id 用作商业价值”的规则。但我无法真正激发它。

【问题讨论】:

  • 一味地遵守规则是万恶之源。没有适用于所有编程的通用规则,不要让任何人告诉你。基本上这取决于..
  • 根据簿记法(在大多数国家/地区),发票编号应为流水号,不得有任何间隔。因此,为此使用数据库 Id 将导致可能存在这些差距,从而违反该规则
  • 根据wiki,一些人认为代理不应该具有语义意义。个人觉得没关系。标识列的重点是提供一个自动的唯一值。
  • @LeiYang (cc @Fabio): 如果你在一个事务中创建了一条会被回滚的记录,那么下一条记录不会重用这个id。
  • @Liam,一味地遵守规则是万恶之源。 - 不要告诉年轻的开发者 ;)

标签: c# database anti-patterns


【解决方案1】:

不要将 id 用作商业价值

您可以应用用于激励关注点分离的相同解释。

如果您在业务逻辑代码中使用Id 的实现细节的功能,例如由数据库生成,这意味着您的业务逻辑依赖于数据库实现。

Id 有一个责任 - 提供唯一值,通过它您可以识别实体并将其与其他相关实体链接。因此,在您的业务逻辑中,您只能将 Id 值用于相等条件。

例如,如果您有由数据库生成的integer 类型的Id
而且你在业务逻辑条件中的某个地方

if (Id == 0)
{
    return "new";
}

您的业务逻辑将取决于Id 实现(类型)。这意味着您只能使用价值为integerId,并且不能将其更改为Guid

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2014-08-21
    • 2021-09-09
    相关资源
    最近更新 更多