Подтвердить что ты не робот

SignInManager.PasswordSignInAsync генерирует много доступа к базе данных

В моем приложении я использую идентификатор ASP.NET. Все прекрасно работает, но, тестируя, я обнаружил, что следующая команда создает множество запросов к базе данных: SignInManager.PasswordSignInAsync:

var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: true);

Я замечаю эту проблему при тестировании приложения с использованием теста производительности. Тест показывает, что для запроса ответа на вход требуется огромное время. На следующем рисунке показан результат теста производительности для запроса на вход: введите описание изображения здесь.

Затем я использую SQL Server Profiler для проверки того, что происходит, когда выполняется команда SignInManager.PasswordSignInAsync. Он показывает, что генерируется большое количество запросов к базе данных. Из SQL Server Profiler взято следующее:

exec sp_executesql N'SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserFullName] AS [UserFullName], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[Online] AS [Online], 
    [Extent1].[LastOnlineDate] AS [LastOnlineDate], 
    [Extent1].[BrithDate] AS [BrithDate], 
    [Extent1].[Job] AS [Job], 
    [Extent1].[Gender] AS [Gender], 
    [Extent1].[CountryId] AS [CountryId], 
    [Extent1].[LivesIn] AS [LivesIn], 
    [Extent1].[RelationId] AS [RelationId], 
    [Extent1].[Religion] AS [Religion], 
    [Extent1].[FirstSchool] AS [FirstSchool], 
    [Extent1].[SecondSchool] AS [SecondSchool], 
    [Extent1].[University] AS [University], 
    [Extent1].[ContactInfo] AS [ContactInfo], 
    [Extent1].[Email] AS [Email], 
    [Extent1].[EmailConfirmed] AS [EmailConfirmed], 
    [Extent1].[PasswordHash] AS [PasswordHash], 
    [Extent1].[SecurityStamp] AS [SecurityStamp], 
    [Extent1].[PhoneNumber] AS [PhoneNumber], 
    [Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
    [Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
    [Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
    [Extent1].[LockoutEnabled] AS [LockoutEnabled], 
    [Extent1].[AccessFailedCount] AS [AccessFailedCount], 
    [Extent1].[UserName] AS [UserName]
    FROM [dbo].[AspNetUsers] AS [Extent1]
    WHERE ((UPPER([Extent1].[UserName])) = (UPPER(@p__linq__0))) OR ((UPPER([Extent1].[UserName]) IS NULL) AND (UPPER(@p__linq__0) IS NULL))',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'[email protected]'

exec sp_executesql N'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[ClaimType] AS [ClaimType], 
    [Extent1].[ClaimValue] AS [ClaimValue]
    FROM [dbo].[AspNetUserClaims] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103

exec sp_executesql N'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[ClaimType] AS [ClaimType], 
    [Extent1].[ClaimValue] AS [ClaimValue]
    FROM [dbo].[AspNetUserClaims] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103

exec sp_executesql N'SELECT 
    [Extent1].[LoginProvider] AS [LoginProvider], 
    [Extent1].[ProviderKey] AS [ProviderKey], 
    [Extent1].[UserId] AS [UserId]
    FROM [dbo].[AspNetUserLogins] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[RoleId] AS [RoleId]
    FROM [dbo].[AspNetUserRoles] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserFullName] AS [UserFullName], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[Online] AS [Online], 
    [Extent1].[LastOnlineDate] AS [LastOnlineDate], 
    [Extent1].[BrithDate] AS [BrithDate], 
    [Extent1].[Job] AS [Job], 
    [Extent1].[Gender] AS [Gender], 
    [Extent1].[CountryId] AS [CountryId], 
    [Extent1].[LivesIn] AS [LivesIn], 
    [Extent1].[RelationId] AS [RelationId], 
    [Extent1].[Religion] AS [Religion], 
    [Extent1].[FirstSchool] AS [FirstSchool], 
    [Extent1].[SecondSchool] AS [SecondSchool], 
    [Extent1].[University] AS [University], 
    [Extent1].[ContactInfo] AS [ContactInfo], 
    [Extent1].[Email] AS [Email], 
    [Extent1].[EmailConfirmed] AS [EmailConfirmed], 
    [Extent1].[PasswordHash] AS [PasswordHash], 
    [Extent1].[SecurityStamp] AS [SecurityStamp], 
    [Extent1].[PhoneNumber] AS [PhoneNumber], 
    [Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
    [Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
    [Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
    [Extent1].[LockoutEnabled] AS [LockoutEnabled], 
    [Extent1].[AccessFailedCount] AS [AccessFailedCount], 
    [Extent1].[UserName] AS [UserName]
    FROM [dbo].[AspNetUsers] AS [Extent1]
    WHERE [Extent1].[Id] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[ClaimType] AS [ClaimType], 
    [Extent1].[ClaimValue] AS [ClaimValue]
    FROM [dbo].[AspNetUserClaims] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[LoginProvider] AS [LoginProvider], 
    [Extent1].[ProviderKey] AS [ProviderKey], 
    [Extent1].[UserId] AS [UserId]
    FROM [dbo].[AspNetUserLogins] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103

    exec sp_executesql N'SELECT 
        [Extent1].[UserId] AS [UserId], 
        [Extent1].[RoleId] AS [RoleId]
        FROM [dbo].[AspNetUserRoles] AS [Extent1]
        WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
    exec sp_executesql N'SELECT TOP (1) 
        [Extent1].[Id] AS [Id], 
        [Extent1].[UserFullName] AS [UserFullName], 
        [Extent1].[UserId] AS [UserId], 
        [Extent1].[Online] AS [Online], 
        [Extent1].[LastOnlineDate] AS [LastOnlineDate], 
        [Extent1].[BrithDate] AS [BrithDate], 
        [Extent1].[Job] AS [Job], 
        [Extent1].[Gender] AS [Gender], 
        [Extent1].[CountryId] AS [CountryId], 
        [Extent1].[LivesIn] AS [LivesIn], 
        [Extent1].[RelationId] AS [RelationId], 
        [Extent1].[Religion] AS [Religion], 
        [Extent1].[FirstSchool] AS [FirstSchool], 
        [Extent1].[SecondSchool] AS [SecondSchool], 
        [Extent1].[University] AS [University], 
        [Extent1].[ContactInfo] AS [ContactInfo], 
        [Extent1].[Email] AS [Email], 
        [Extent1].[EmailConfirmed] AS [EmailConfirmed], 
        [Extent1].[PasswordHash] AS [PasswordHash], 
        [Extent1].[SecurityStamp] AS [SecurityStamp], 
        [Extent1].[PhoneNumber] AS [PhoneNumber], 
        [Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
        [Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
        [Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
        [Extent1].[LockoutEnabled] AS [LockoutEnabled], 
        [Extent1].[AccessFailedCount] AS [AccessFailedCount], 
        [Extent1].[UserName] AS [UserName]
        FROM [dbo].[AspNetUsers] AS [Extent1]
        WHERE [Extent1].[Id] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
    exec sp_executesql N'SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[UserId] AS [UserId], 
        [Extent1].[ClaimType] AS [ClaimType], 
        [Extent1].[ClaimValue] AS [ClaimValue]
        FROM [dbo].[AspNetUserClaims] AS [Extent1]
        WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[LoginProvider] AS [LoginProvider], 
    [Extent1].[ProviderKey] AS [ProviderKey], 
    [Extent1].[UserId] AS [UserId]
    FROM [dbo].[AspNetUserLogins] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[RoleId] AS [RoleId]
    FROM [dbo].[AspNetUserRoles] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserFullName] AS [UserFullName], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[Online] AS [Online], 
    [Extent1].[LastOnlineDate] AS [LastOnlineDate], 
    [Extent1].[BrithDate] AS [BrithDate], 
    [Extent1].[Job] AS [Job], 
    [Extent1].[Gender] AS [Gender], 
    [Extent1].[CountryId] AS [CountryId], 
    [Extent1].[LivesIn] AS [LivesIn], 
    [Extent1].[RelationId] AS [RelationId], 
    [Extent1].[Religion] AS [Religion], 
    [Extent1].[FirstSchool] AS [FirstSchool], 
    [Extent1].[SecondSchool] AS [SecondSchool], 
    [Extent1].[University] AS [University], 
    [Extent1].[ContactInfo] AS [ContactInfo], 
    [Extent1].[Email] AS [Email], 
    [Extent1].[EmailConfirmed] AS [EmailConfirmed], 
    [Extent1].[PasswordHash] AS [PasswordHash], 
    [Extent1].[SecurityStamp] AS [SecurityStamp], 
    [Extent1].[PhoneNumber] AS [PhoneNumber], 
    [Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
    [Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
    [Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
    [Extent1].[LockoutEnabled] AS [LockoutEnabled], 
    [Extent1].[AccessFailedCount] AS [AccessFailedCount], 
    [Extent1].[UserName] AS [UserName]
    FROM [dbo].[AspNetUsers] AS [Extent1]
    WHERE [Extent1].[Id] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103
exec sp_executesql N'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[ClaimType] AS [ClaimType], 
    [Extent1].[ClaimValue] AS [ClaimValue]
    FROM [dbo].[AspNetUserClaims] AS [Extent1]
    WHERE [Extent1].[UserId] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=2103

Вышеупомянутые запросы являются лишь частью результата. Те же запросы выполняются несколько раз. Это нормальный случай или есть проблема?

Если это проблема, как ее можно решить.

4b9b3361

Ответ 1

Я собираюсь предположить, что вы используете настройку Identity "как есть". В этом случае вы также, вероятно, будете использовать Entity Framework.

Чтобы ответить на ваш вопрос: по моему опыту, пользовательское хранилище, которое находится за пределами UserManager, SignInManager и т.д., открывается несколько раз, когда действие выполняется.

Основная проблема, которую я заметил, это было невероятно медленным с EntityFramework на месте. Я обнаружил, что если бы я создал свой собственный CustomUserStore, это резко ускорило скорость входа/пользователя. Существуют еще несколько вызовов, но они намного лучше.

В моем случае я использовал Micro-ORM Dapper.NET для управления моим новым UserStore. Dapper может выполнять запросы намного быстрее, чем EntityFramework (в 3-10 раз быстрее в зависимости от запроса в некоторых тестах): https://www.exceptionnotfound.net/dapper-vs-entity-framework-vs-ado-net-performance-benchmarking/)

Dapper.NET: https://github.com/StackExchange/Dapper

С помощью пользовательской перезаписи UserStore вы можете найти множество примеров в Интернете, но вот один из них: https://markjohnson.io/articles/exorcising-entity-framework-from-asp-net-identity/