GetUserId in WebMatrix.WebData.SimpleMembershipProvider is defined like this:
```
internal static int GetUserId(IDatabase db, string userTableName, string userNameColumn, string userIdColumn, string userName)
{
// Casing is normalized in Sql to allow the database to normalize username according to its collation. The common issue
// that can occur here is the 'Turkish i problem', where the uppercase of 'i' is not 'I' in Turkish.
var result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (UPPER(" + userNameColumn + ") = UPPER(@0))", userName);
if (result != null)
{
return (int)result;
}
return -1;
}
```
Consider a large system with a bigger user database. The UserId column will be the clustered index, and an additional index for the UserName column will be added.
Now using UPPER() forces a scan touching every row in the table completely disregarding the index. It might not be an issue for smaller systems, but with a sample database with 8 millon users the query takes 3.5 seconds on my machine vs 11 milliseconds without UPPER(). That will effectively bring a bigger system to a halt.
I think there is probably a carefully chosen collation already since we are able to use our own tables. If we have chosen a CI or a CS collation i think it should be respected.
If you think UPPER is neccesary, then I argue the value should be stored in uppercase from the beginning. Since it's a table that simpleMembership doesn't own, there should be an additional field userIdColumn + 'Upper'.
Even better in my opinion would be support for stored procedures, since it would give the added benefit of being able to run a system without select or update rights, only execute on a chosen schema.
Then it would be very easy to improve the tsql to suit the specific solution.
```
internal static int GetUserId(IDatabase db, string userTableName, string userNameColumn, string userIdColumn, string userName)
{
// Casing is normalized in Sql to allow the database to normalize username according to its collation. The common issue
// that can occur here is the 'Turkish i problem', where the uppercase of 'i' is not 'I' in Turkish.
var result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (UPPER(" + userNameColumn + ") = UPPER(@0))", userName);
if (result != null)
{
return (int)result;
}
return -1;
}
```
Consider a large system with a bigger user database. The UserId column will be the clustered index, and an additional index for the UserName column will be added.
Now using UPPER() forces a scan touching every row in the table completely disregarding the index. It might not be an issue for smaller systems, but with a sample database with 8 millon users the query takes 3.5 seconds on my machine vs 11 milliseconds without UPPER(). That will effectively bring a bigger system to a halt.
I think there is probably a carefully chosen collation already since we are able to use our own tables. If we have chosen a CI or a CS collation i think it should be respected.
If you think UPPER is neccesary, then I argue the value should be stored in uppercase from the beginning. Since it's a table that simpleMembership doesn't own, there should be an additional field userIdColumn + 'Upper'.
Even better in my opinion would be support for stored procedures, since it would give the added benefit of being able to run a system without select or update rights, only execute on a chosen schema.
Then it would be very easy to improve the tsql to suit the specific solution.