44 lines
1.3 KiB
C#
44 lines
1.3 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Storage;
|
|
|
|
public class MrnGenerator : IMrnGenerator
|
|
{
|
|
private readonly AppDbContext _db;
|
|
private const string MrnPrefix = "VCR";
|
|
private const string SequenceName = "clinical.mrn_sequence";
|
|
|
|
public MrnGenerator(AppDbContext db)
|
|
{
|
|
_db = db;
|
|
}
|
|
|
|
public async Task<string> GenerateNextMrnAsync()
|
|
{
|
|
// Use PostgreSQL sequence for atomic, gap-free numbering
|
|
var connection = _db.Database.GetDbConnection();
|
|
var wasOpen = connection.State == System.Data.ConnectionState.Open;
|
|
|
|
if (!wasOpen)
|
|
await connection.OpenAsync();
|
|
|
|
try
|
|
{
|
|
using var command = connection.CreateCommand();
|
|
command.CommandText = $"SELECT nextval('{SequenceName}')";
|
|
|
|
// If we're in a transaction, enlist the command
|
|
if (_db.Database.CurrentTransaction is not null)
|
|
{
|
|
command.Transaction = _db.Database.CurrentTransaction.GetDbTransaction();
|
|
}
|
|
|
|
var nextVal = (long)(await command.ExecuteScalarAsync())!;
|
|
return $"{MrnPrefix}-{nextVal:D6}";
|
|
}
|
|
finally
|
|
{
|
|
if (!wasOpen)
|
|
await connection.CloseAsync();
|
|
}
|
|
}
|
|
} |