I have the repository method inside my asp.net mvc web application, to automatically generate a unique sequence number called Tag:-
public void InsertOrUpdat
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.
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);
}
}