ASP.net身份更改密码效率低下

ASP.net身份更改密码效率低下,asp.net,authentication,asp.net-identity,Asp.net,Authentication,Asp.net Identity,我正在使用用户id为整数的ASP.net Identity 2.0。执行密码更新是一项极其昂贵的数据库操作,根据我拥有的数据量,有2个(不需要的)查询,平均为128407 db时间单位,或者在查询计划中约为7 我正在调用的代码(异步或同步都是相同的) 在数据库中,这会导致两个大型sql调用,它们的内部包含 AspNetUserRoles ... WHERE ((UPPER([Extent1].[Email])) = (UPPER(@p__linq__0))) ... query 2: AspN

我正在使用用户id为整数的ASP.net Identity 2.0。执行密码更新是一项极其昂贵的数据库操作,根据我拥有的数据量,有2个(不需要的)查询,平均为128407 db时间单位,或者在查询计划中约为7

我正在调用的代码(异步或同步都是相同的)

在数据库中,这会导致两个大型sql调用,它们的内部包含

AspNetUserRoles ... WHERE ((UPPER([Extent1].[Email])) = (UPPER(@p__linq__0))) ...

query 2:
AspNetUserRoles ... WHERE ((UPPER([Extent1].[UserName])) = (UPPER(@p__linq__0))) ...
在我看来

  • 根本没有理由调用此sql—通过int ID进行查找很快,并且它调用的sql正在查找角色数据
  • 使用“Upper”可能是它速度慢的原因,如果没有其他更好的解决方案,我可以添加一个计算索引()

从高层次上讲,我的问题是——是否有解决方案,或者身份团队是否有人可以修复代码(如果代码确实损坏)

更新 对于以下调用(可能还有许多其他调用),可以观察到相同的行为

  • UserManager.ResetPasswordAsync
  • UserManager.CreateAsync

    • 当然,您可以自己做,而不是调用该方法

      假设您在范围中有一个名为UserManager的UserManager和一个名为context的DbContext

      var user = await context.Users.Single(u => u.Id == knownId);
      // You can skip this if you don't care about checking the old password...
      if (userManager.PasswordHasher.VerifyHashedPassword(user.HashedPassword, "myOldPassword") == PasswordVerificationResult.Failed) { return; };
      user.HashedPassword = userManager.PasswordHasher.HashPassword("myNewPassword");
      await context.SaveChangesAsync();
      
      如果仍然没有对其进行足够的优化,DbContext将公开一个Sql方法,因此您可以使用密码哈希器获取一个哈希,然后发出一个Update()查询


      我不会做这两件事,除非这真的是一个瓶颈或者你有其他好的理由。我在我的应用程序中也做了类似的事情,因为至少在ASP.NET Identity v1中,没有任何方法可以在不检查旧密码的情况下更改密码。

      我相信@emodernoket提供的答案正确有效地回答了我最初的问题。由于需要在短期内修改API的许多部分,因此我将使用一个更简单的解决方案(但不是很好的解决方案)

      在电子邮件和用户名上添加计算并持久化的索引

      ALTER TABLE dbo.aspnetusers ADD UpperFieldEmail AS UPPER(email) PERSISTED 
      CREATE NONCLUSTERED INDEX IX_aspnetusers_UpperFieldEmail  ON dbo.aspnetusers(UpperFieldEmail)
      
      ALTER TABLE dbo.aspnetusers ADD UpperFieldUsername AS UPPER(username) PERSISTED 
      CREATE NONCLUSTERED INDEX IX_aspnetusers_UpperFieldUsername ON dbo.aspnetusers(UpperFieldUsername)
      

      “或者身份团队的人可以修复代码(如果代码确实已损坏)。”这更像是对Microsoft Connect的请求。在正常情况下,这可能应该作为离题而关闭,因为这更像是Microsoft错误报告。但是,我建议在这种情况下我们将此问题保留为打开状态,以便在此处指出最终的连接票证,并将最终的解决方案作为答案发布。登录地址:此问题已通过ASP.NET Identity 2.2.0版本修复。验证此答案比本机调用更有效。注意:标识为2.0的是user.PasswordHash,在调用此代码之前,请小心验证密码是否有效(长度等)。啊,对不起,我仍在使用版本1。
      ALTER TABLE dbo.aspnetusers ADD UpperFieldEmail AS UPPER(email) PERSISTED 
      CREATE NONCLUSTERED INDEX IX_aspnetusers_UpperFieldEmail  ON dbo.aspnetusers(UpperFieldEmail)
      
      ALTER TABLE dbo.aspnetusers ADD UpperFieldUsername AS UPPER(username) PERSISTED 
      CREATE NONCLUSTERED INDEX IX_aspnetusers_UpperFieldUsername ON dbo.aspnetusers(UpperFieldUsername)