Since this functionality doesn't come out of the box, I came up to write an extension-class for the DbContext that does the job. Have a look at this chunk of code:
public enum Sequence
{
[Description("sequence__name__goes__here")]
ClientNr,
[Description("another__sequence__name")]
OrderNr,
}
public static class MyDbContextExtensions
{
public static int NextValueForSequence(this MyDbContext pCtx, Sequence pSequence)
{
SqlParameter result = new SqlParameter("@result", System.Data.SqlDbType.Int)
{
Direction = System.Data.ParameterDirection.Output
};
var sequenceIdentifier = pSequence.GetType()
.GetMember(pSequence.ToString())
.First()
.GetCustomAttribute<DescriptionAttribute>()
.Description;
pCtx.Database.ExecuteSqlCommand($"SELECT @result = (NEXT VALUE FOR [{sequenceIdentifier}]);", result);
return (int)result.Value;
}
}
While I must admit that all that stuff with reflection and annotations for some might seem like an overkill, I still kinda like it.
It allows me to retrieve the value in a pretty elegant way
ctx.NextValueForSequence(Sequence.OrderNr);
It also mocks a "type proof" way, constraining me to explicitly define the different sequence names in a centralized location rather than just passing magic strings from anywhere I want.
If you don't want it that way, just change the method in order to pass the sequence name as a string. It would work just as fine.