【问题标题】:Load user extract with stored procedure使用存储过程加载用户数据提取
【发布时间】:2015-06-16 09:24:48
【问题描述】:

我有一个 ASP MVC Web 应用程序,它需要每天从文件中加载用户提取。数据库中的用户应相应更新:如果不在源中则删除,如果在源和目标中则更新,如果仅在源中则创建。在这样做的同时,某些权利也应该自动授予用户。如果有任何错误,什么都不会发生。

首先我尝试使用 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对应RoleId 2,Right 3对应RoleId3。

【问题讨论】:

  • 不能使用 if else if 吗?
  • 你的意思是在合并语句中使用 if else if 吗?还是您的意思是在没有合并的情况下编写程序?
  • 编写 storproc 而不合并,只使用 if else if
  • 为提出一个好问题点赞! 风格不错!很遗憾,我现在没有时间回答这个问题;(

标签: sql-server asp.net-mvc-3 tsql stored-procedures


【解决方案1】:

阅读完问题后,我想为解决方案留下一个想法。 对我来说,使用 IF / ELSE 来调用更新或插入更有意义,而不是使用合并,因为您需要正在更新/插入的 UserId 来添加它的角色权限。

您可以检查 UId 是否存在,如果存在则更新用户详细信息,如果不存在则创建并保留新的 Identity 值。

在这两种情况下,当用户 ID 使用 IF 语句根据布尔值添加相应的权限时。

伪代码:

If UserId exists in UsersTable
   Update
   Store UserId
Else
   Insert
   Store created UserId (using the @@IDENTITY)

If bool1 add permission 1
If bool3 add permission 2
If bool3 add permission 3

【讨论】:

    猜你喜欢
    • 2018-05-14
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多