低效的SQL在登录/全表扫描(UserStore.FindByNameAsync)



我们正在使用Asp。Oracle数据库上的Net Identity 2.2.1和EF 6.1.3版本。

我们确实在UPPER(USERNAME)上的用户表上有一个索引,但是对于每个用户登录,我们仍然对用户表进行全表扫描。

这个问题似乎是由UserStore中的代码引起的:

public virtual Task<TUser> FindByNameAsync(string userName)
{
  this.ThrowIfDisposed();
  return this.GetUserAggregateAsync((
    Expression<Func<TUser, bool>>) (u =>
    u.UserName.ToUpper() == userName.ToUpper()));
}

将生成带有

的SQL
WHERE (((UPPER("Extent1".USERNAME)) = :p__linq__0) 
OR ((UPPER("Extent1".USERNAME) IS NULL) AND
    (:p__linq__0 IS NULL)))

和OR部分似乎使优化器选择全表扫描。

当使用SQL Server时,可以将where语句修改为:

public virtual Task<TUser> FindByNameAsync(string userName)
{
  this.ThrowIfDisposed();
  var uName = userName.ToUpper();
  return this.GetUserAggregateAsync((
    Expression<Func<TUser, bool>>) (u =>
    u.UserName.ToUpper() == uName));
}

和where部分现在是:

WHERE N'<USERNAME>' = (UPPER([Extent1].[USERNAME]))

但是我失去了如何在使用Oracle时优化这个选项。我试过两种Oracle。管理司机和司机。当在字段上使用UPPER函数时,它们都生成带有OR的where语句。

数据库中需要有大小写不敏感的用户名。

那么,当我们使用UPPER(field) =某些东西时,为什么EF生成一个带有OR语句的SQL ?

还有别的办法吗?有人有好的解决方案吗?

此时,我们的最后一个选择可能是将数据表中的用户名设置为UPPERCASE,从而避免使用UPPER函数——但这似乎不是最佳解决方案。

有没有试过设置

context.UseDatabaseNullSemantics = true;

https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbcontextconfiguration.usedatabasenullsemantics (v = vs.113) . aspx

相关内容

  • 没有找到相关文章

最新更新