Alternatives to using Max+1 to create a user friendly unique sequence numbers

后端 未结 2 1004
孤独总比滥情好
孤独总比滥情好 2020-12-22 07:27

I have the repository method inside my asp.net mvc web application, to automatically generate a unique sequence number called Tag:-

public void InsertOrUpdat         


        
相关标签:
2条回答
  • 2020-12-22 07:40

    If the new sequences in SQL 2012 are not an option (because you can't upgrade) you could create a table that stores the last sequence numbers.

    In the EF context the representing class would look like

    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; }
    
        [Timestamp]
        public byte[] Rowversion { get; set; }
    }
    

    And the barebone procedure to use it:

    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
        }
    }
    

    (You'll have to fit it in into your repository object)

    The concurrency check is there to prevent concurrent users form drawing the same number. The Rowversion ensures that updates are only allowed if its value did not change between fetching the record and updating it.

    0 讨论(0)
  • 2020-12-22 07:46

    A complete solution to this problem would be to combine the use of an auto incrementing column and computed column.

    The table would look something like this:

    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)
    )   
    

    With a mapping:

    public class SomeDataMap : EntityTypeConfiguration<SomeData>
    {
        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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题