实体框架中的自动递增列

Posted

技术标签:

【中文标题】实体框架中的自动递增列【英文标题】:Automatically incremented column in Entity Framework 【发布时间】:2019-01-27 16:20:06 【问题描述】:

假设我有以下实体框架实体:

public class FileDownload

    [Key]
    public int Id  get; set; 

    public int FileTypeId  get; set; 

    public int FileHeaderId  get; set; 

对于每个下载的 FileType,我希望 FileHeaderId 有点像主键。

所以我想要如下结构记录结构:

 ID    FileTypeId        FileHeaderId

 1         1                   1
 2         1                   2
 3         2                   1
 4         2                   2
 5         3                   1
 6         3                   2
 7         3                   3
 8         1                   3
 9         2                   3
10         1                   4

是否可以在保存记录时自动设置?

我不想查找最后一个 id 然后将其增加 1。

FileHeaderId 在每个文件中使用,并且对于每种文件类型必须是唯一的。

谢谢

【问题讨论】:

为什么要生成客户特定订单号?为什么没有不依赖于客户 ID 的订单号? 简短的回答是——很难。您需要有一个唯一的索引来处理不可避免的冲突(以及用于重试的 C# 代码)。您需要进行要避免的查找。您需要考虑边缘情况,例如“如果我删除特定客户的订单会发生什么?” (即订单号重复使用)。这就是为什么大多数系统不能以这种方式工作的原因——它们不使用客户特定订单号。 你试过设置 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 属性吗? 好的,忘记客户订单 ID。那只是我输入的一个虚拟类来解释问题 你为什么“需要”那个?改变“需求”,使用简单、可扩展的设计。此外,实现您想要的任何方式都是特定于数据库的,我们不知道您的目标是什么数据库。 【参考方案1】:

如果您无法更改不使用序列号而是使用 Guid 或 Date 的要求,那么您将不得不做 1 个

    查找以获取代码中的最后一个序列号。 或者在数据库中有一个数据库触发器或其他东西来设置正确的序列号。

关于 #1 有一些注意事项:

    可以删除记录吗?重复使用序列号会有问题吗? 记录是否由多个线程创建。如果是,您无法确定递增的最后一个序列号确实是最后一个,您可能需要另一个表来同步/锁定索引,以免它们被占用两次或更多。

我仍然建议重新审视架构,因为使用当前的方法可能会有太多不必要的复杂性,可以通过稍微更改表架构来避免。

【讨论】:

以上是关于实体框架中的自动递增列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用实体框架中的 DBContext 获取在另一列中具有重复数据的所有 ID?

数据库表的列中的值的下拉列表-MVC实体框架

如果我们使用自动递增的标识列和PK,则违反3NF

将递增值与其他值一起添加到 Oracle 数据库中的列中

在不修改实体类(注释)或数据上下文(使用 fluentapi)的情况下禁用标识(自动递增)

DB2 根据另一列中的不同值更新具有递增数字的列