使用Max + 1创建用户友好的唯一序列号的替代方法

我在我的asp.net mvc web应用程序中有了存储库方法,以自动生成一个名为Tag的唯一序列号: –

public void InsertOrUpdateServer(TMSServer server, string username) { if (server.TMSServerID == default(int)) { // New entity int technologyypeID = GetTechnologyTypeID("Server"); Technology technology = new Technology { IsDeleted = true, Tag = "S" + GetTagMaximumeNumber(technologyypeID).ToString(), StartDate = DateTime.Now, }; Save(); //code goes here 

GetTagMaximumeNumber()函数的位置是: –

 public int GetTagMaximumeNumber(int typeID) { string s = tms.Technologies.Where(a => a.TypeID == typeID).Max(a2 => a2.Tag.Substring(1)); if (s != null) { return Int32.Parse(s) + 1; } else { return 100;//if this is the first record created }} 

以上将获得标签的最大数量并添加1然后尝试将其保存到数据库中。 以上工作正常,但我确信在多个用户将添加记录的生产服务器上,将生成相同的标记号,并且在尝试添加数据库中已存在的自动生成的标记号时将引发exception。 所以我有以下问题:-1

  1. 为了使序列号始终是唯一的,我可以遵循的其他方法是什么。

  2. 在我目前的方法中,标签号码的差距很小。 只有在用户删除记录且其标记号不是最大值时才会出现间隙。 那么有没有办法在任何新方法中都有这个,所以差距会很小?

谢谢您的帮助。

该问题的完整解决方案是结合使用自动递增列和计算列。

该表看起来像这样:

 CREATE TABLE [dbo].[somedata]( [id] [bigint] IDENTITY(1,1) NOT NULL, [reference] [varchar](50) NULL, [STag] AS ('S'+CONVERT([varchar](19),[id],(0))), CONSTRAINT [PK_somedata] PRIMARY KEY CLUSTERED ([id] ASC) ) 

有了映射:

 public class SomeDataMap : EntityTypeConfiguration { public SomeDataMap() { // Primary Key this.HasKey(t => t.id); // Properties this.Property(t => t.id) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); this.Property(t => t.reference) .HasMaxLength(50); this.Property(t => t.STag) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); } } 

如果SQL 2012中的新序列不是一个选项(因为您无法升级),则可以创建一个存储最后序列号的表。

在EF上下文中,表示类看起来像

 class TaggedSequence { [Key] public int Id { get; set; } [Required] public int Last { get; set; } [Required] [Column(TypeName = "CHAR"), StringLength(1)] public string Tag { get; set; } 1541568071 public byte[] Rowversion { get; set; } } 

以及使用它的准系统程序:

 using (var context = new MyContext()) { try { var tag = "S"; var sequence = context.TaggedSequence.Single(s => s.Tag == tag); sequence.Last += 1; Technology technology = new Technology { ... }; technology.Id = tag + sequence.Last; context.Technologies.Add(technology); context.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { // Retry } } 

(您必须将其放入存储库对象中)

并发检查是为了防止并发用户形成相同的数字。 Rowversion确保只有在获取记录和更新记录之间其值没有变化时才允许更新。