Почему вы используете ADO.net Entity Framework для работы, которая походит на работу ETL? (См. Критический анализ ADO.NET Entity Framework и ORM в целом ниже. Он является бесплатным).
Зачем вообще использовать целые? Использование uniqueidentifier решит проблему «несколько экземпляров запущенного приложения».
Использование uniqueidentifier в качестве столбца по умолчанию будет медленнее, чем использование int IDENTITY ... для создания guid требуется больше времени, чем для int. Guid также будет больше (16 байт), чем int (4 байта). Попробуйте сначала, и если это приведет к приемлемой производительности, запустите его.
Если задержка, вызванная созданием guid в каждой строке, вставляет ее недопустимо, создайте guid навалом (или на другом сервере) и кэшируйте их в таблицу.
Пример кода TSQL:
CREATE TABLE testinsert
(
date_generated datetime NOT NULL DEFAULT GETDATE(),
guid uniqueidentifier NOT NULL,
TheValue nvarchar(255) NULL
)
GO
CREATE TABLE guids
(
guid uniqueidentifier NOT NULL DEFAULT newid(),
used bit NOT NULL DEFAULT 0,
date_generated datetime NOT NULL DEFAULT GETDATE(),
date_used datetime NULL
)
GO
CREATE PROCEDURE GetGuid
@guid uniqueidentifier OUTPUT
AS
BEGIN
SET NOCOUNT ON
DECLARE @return int = 0
BEGIN TRY
BEGIN TRANSACTION
SELECT TOP 1 @guid = guid FROM guids WHERE used = 0
IF @guid IS NOT NULL
UPDATE guids
SET
used = 1,
date_used = GETDATE()
WHERE guid = @guid
ELSE
BEGIN
SET @return = -1
PRINT 'GetGuid Error: No Unused guids are available'
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SET @return = ERROR_NUMBER() -- some error occurred
SET @guid = NULL
PRINT 'GetGuid Error: ' + CAST(ERROR_NUMBER() as varchar) + CHAR(13) + CHAR(10) + ERROR_MESSAGE()
ROLLBACK
END CATCH
RETURN @return
END
GO
CREATE PROCEDURE InsertIntoTestInsert
@TheValue nvarchar(255)
AS
BEGIN
SET NOCOUNT ON
DECLARE @return int = 0
DECLARE @guid uniqueidentifier
DECLARE @getguid_return int
EXEC @getguid_return = GetGuid @guid OUTPUT
IF @getguid_return = 0
BEGIN
INSERT INTO testinsert(guid, TheValue) VALUES (@guid, @TheValue)
END
ELSE
SET @return = -1
RETURN @return
END
GO
-- generate the guids
INSERT INTO guids(used) VALUES (0)
INSERT INTO guids(used) VALUES (0)
--Insert data through the stored proc
EXEC InsertIntoTestInsert N'Foo 1'
EXEC InsertIntoTestInsert N'Foo 2'
EXEC InsertIntoTestInsert N'Foo 3' -- will fail, only two guids were created
-- look at the inserted data
SELECT * FROM testinsert
-- look at the guids table
SELECT * FROM guids
Забавный вопрос ... как вы сопоставляете это с Entity Framework ADO.Net?
Это классическая проблема, которая началась в первые дни ORM (Object Relational Mapping).
Если вы используете лучшие методы работы с реляционными базами данных (никогда не разрешаете прямой доступ к базовым таблицам, разрешаете манипулировать данными только с помощью представлений и хранимых процедур), то вы добавляете численность персонала (кто-то способен и хочет писать не только схему базы данных, но и все представления и хранимые процедуры, которые формируют API) и вносят задержку (время, чтобы фактически написать этот материал) в проект.
Таким образом, все обрезают это, и люди пишут запросы непосредственно к нормализованной базе данных, которую они не понимают ... таким образом, потребность в ORM, в данном случае, ADO.NET Entity Framework.
ORM пугает меня до чертиков. Я видел, как инструменты ORM генерируют ужасно неэффективные запросы, которые ставят серверы баз данных с отличной производительностью на колени. То, что было достигнуто в производительности программиста, было потеряно в ожидании конечного пользователя и разочаровании администратора.