У меня есть веб-приложение ASP MVC, которое требуется для ежедневного загрузки пользователя из файла. Пользователи в базе данных должны быть соответствующим образом обновлены: удалены, если не в источнике, обновлены, если в исходном и целевом, и созданы, если только в источнике. При этом определенные права также должны автоматически предоставляться пользователям. Если есть какая-либо ошибка, ничего не должно произойти вообще.Загрузить выдержку пользователя с помощью хранимой процедуры
Сначала я попытался сделать это с помощью Entity Framework, но для вызова SaveChanges требуется около двух минут, что очень важно для относительно небольшого количества пользователей (~ 140 000).
Теперь я хочу написать хранимую процедуру, которая будет выполнять обновление. Я бы передал список новых пользователей в качестве параметра. Тип моей временной таблицы:
CREATE TYPE [dbo].[TempUserType] AS TABLE
(
[Uid] NVARCHAR(80) NOT NULL PRIMARY KEY,
[GivenName] NVARCHAR(80) NOT NULL,
[FamilyName] NVARCHAR(80) NOT NULL,
[Email] NVARCHAR(256) NOT NULL,
[GiveRight1] BIT NOT NULL,
[GiveRight2] BIT NOT NULL,
[GiveRight3] BIT NOT NULL
)
Пользователи:
CREATE TABLE [dbo].[User] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Uid] NVARCHAR (80) NOT NULL,
[GivenName] NVARCHAR (80) NOT NULL,
[FamilyName] NVARCHAR (80) NOT NULL,
[Email] NVARCHAR (256) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
UNIQUE NONCLUSTERED ([Uid] ASC)
);
Роли пользователей:
CREATE TABLE [dbo].[UserRole] (
[UserId] INT NOT NULL,
[RoleId] INT NOT NULL,
CONSTRAINT [PK_UserRole] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
CONSTRAINT [FK_UserRole_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]),
CONSTRAINT [FK_UserRole_Role] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[Role] ([Id])
);
процедура я застрял записывания:
CREATE PROCEDURE [dbo].[UpdateUsers]
@extractedUsers TempUserType READONLY
AS
BEGIN TRANSACTION
MERGE
[dbo].[User] AS trg
USING
@extractedUsers AS src
ON
(trg.[Uid] = src.[Uid])
WHEN MATCHED THEN
UPDATE SET
trg.GivenName = src.GivenName,
trg.FamilyName = src.FamilyName,
trg.Email = src.Email
WHEN NOT MATCHED BY TARGET THEN
INSERT
([Uid], GivenName, FamilyName, Email)
VALUES
(src.[Uid], src.GivenName, src.FamilyName, src.Email)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
COMMIT TRANSACTION
Мой вопрос: используется ли процедура с объединением, подходящая в этом случае для достижения улучшения производительности по сравнению с EF? Как я могу назначить роли в соответствии с 3 булевыми значениями, которые находятся в исходной таблице?
Роли могут быть закодированы, то есть я знаю, что Right1 соответствует RoleId 1, Right 2 to RoleId 2 и Right 3 to RoleId3.
Cant вы используете, если еще если? –
Вы имеете в виду использование if else, если внутри оператора слияния? Или вы хотите написать процедуру без слияния? – user3711864
Написание storproc без слияния и просто использование if else, если –