Вот пример реализации счетчика.Основная идея заключается в использовании триггера вставки для обновления номеров, скажем, счетов.Первый шаг - создать таблицу для хранения значения последнего назначенного номера:
create table [Counter]
(
LastNumber int
)
и инициализировать его одной строкой:
insert into [Counter] values(0)
Пример таблицы счетов-фактур:
create table invoices
(
InvoiceID int identity primary key,
Number varchar(8),
InvoiceDate datetime
)
Хранимая процедура LastNumber сначала обновляет строку счетчика, а затем извлекает значение.Поскольку значение является целым числом, оно просто возвращается как возвращаемое значение процедуры;в противном случае потребуется выходной столбец.Процедура принимает в качестве параметра число следующих чисел для выборки;вывод является последним числом.
create proc LastNumber (@NumberOfNextNumbers int = 1)
as
begin
declare @LastNumber int
update [Counter]
set LastNumber = LastNumber + @NumberOfNextNumbers -- Holds update lock
select @LastNumber = LastNumber
from [Counter]
return @LastNumber
end
Триггер в таблице счетов-фактур получает количество одновременно вставленных счетов-фактур, запрашивает следующие n номеров из хранимой процедуры и обновляет счета-фактуры с этими номерами.
create trigger InvoiceNumberTrigger on Invoices
after insert
as
set NoCount ON
declare @InvoiceID int
declare @LastNumber int
declare @RowsAffected int
select @RowsAffected = count(*)
from Inserted
exec @LastNumber = dbo.LastNumber @RowsAffected
update Invoices
-- Year/month parts of number are missing
set Number = right ('000' + ltrim(str(@LastNumber - rowNumber)), 3)
from Invoices
inner join
( select InvoiceID,
row_number () over (order by InvoiceID desc) - 1 rowNumber
from Inserted
) insertedRows
on Invoices.InvoiceID = InsertedRows.InvoiceID
В случаеоткатов не останется никаких пробелов.Таблица счетчиков может быть легко расширена с помощью ключей для разных последовательностей;в этом случае может пригодиться дата valid-till, поскольку вы можете заранее подготовить эту таблицу и позволить LastNumber беспокоиться о выборе счетчика для текущего года / месяца.
Пример использования:
insert into invoices (invoiceDate) values(GETDATE())
Поскольку значение числового столбца генерируется автоматически, его необходимо перечитать.Я считаю, что у EF есть условия для этого.