HttpContext.Current.User.IsInRole()
вызывает RolePrincipal.IsInRole()
для пользователя, аутентифицированного с помощью FormsAuthentication. Внутренне RolePrincipal.IsInRole()
вызывает SqlRoleProvider.GetRolesForUser()
, что создает и уничтожает объект SqlConnection
в методе.
Могут быть и другие решения на SQL Server, чтобы обойти эту проблему, но со стороны .NET я вижу только следующие варианты:
- Реализация собственного поставщика ролей, чтобы вы могли самостоятельно управлять подключениями к базе данных.
- Реализуйте свой собственный объект
IPrincipal
, чтобы вы могли самостоятельно управлять подключениями к базе данных.
- Предварительно извлеките роли перед началом транзакции SubSonic и при необходимости проверьте список на наличие соответствующей роли.
- Возможно, вам даже не нужно хранить роли, поскольку
RolePrincipal.IsInRole()
кэширует роли при вызове и отправляется в базу данных только в том случае, если кэш пустой или недействителен. Вызов IsInRole()
перед началом транзакции предварительно заполнит кэш объекта RolePrincipal
, что означает, что последующие вызовы в середине транзакции SubSonic будут извлекать роли из кэша, а не подключаться к базе данных для их получения.
Я действительно не уверен, что последняя идея хорошая, так как я уверен, что есть много способов, которые могут пойти не так. Я думаю, что самое простое решение - предварительно выбрать роли до начала транзакции SubSonic.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ: Для полноты, вот реализация RolePrincipal.IsInRole()
, как видно в Reflector:
public bool IsInRole(string role)
{
if (this._Identity == null)
{
throw new ProviderException(SR.GetString("Role_Principal_not_fully_constructed"));
}
if (!this._Identity.IsAuthenticated || (role == null))
{
return false;
}
role = role.Trim();
if (!this.IsRoleListCached)
{
this._Roles.Clear();
foreach (string str in Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name))
{
if (this._Roles[str] == null)
{
this._Roles.Add(str, string.Empty);
}
}
this._IsRoleListCached = true;
this._CachedListChanged = true;
}
return (this._Roles[role] != null);
}