Пользовательский RoleProvider продолжает кэшировать мой объект репозитория - PullRequest
3 голосов
/ 09 февраля 2012

Я реализовал собственный RoleProvider для проекта.RoleProvider работает, но репозиторий, который я использую для выборки пользовательских ролей, заполняется только после сборки.Когда я выходю из системы, меняю роль пользователя, снова захожу, пользователь сохраняет старые роли.

public class CmsRoleProvider : RoleProvider
{
    private EntityDB _db { get; set; }

    public CmsRoleProvider()
    {
        _db = new EntityDB();
    }

    public override string[] GetRolesForUser(string username)
    {
        var user = _db.Users.Where(u => u.EmailAddress == username).SingleOrDefault();
        var roles = user.UserRoles.Select(u => u.Role.Name).ToList<string>();

        return roles.ToArray();
    }
}

В приведенном выше примере пользователь получает правильные роли только после построения проекта.Когда я создаю репозиторий внутри функции GetRolesForUser, он работает нормально.

Есть ли проблема с кэшированием?Кто может помочь мне с этим.

Ответы [ 2 ]

7 голосов
/ 09 февраля 2012

ASP.NET создает только один экземпляр RoleProvider.Из-за этого ваш контекст также долгое время.Лучше иметь краткосрочные контексты.

public class CmsRoleProvider : RoleProvider
{        
    private EntityDB GetContext()
    {
       return new EntityDB();
    }

    public override string[] GetRolesForUser(string username)
    {
        using(var db = GetContext())
        {
            var user = db.Users.Where(u => u.EmailAddress == username)
                          .SingleOrDefault();
            var roles = user.UserRoles.Select(u => u.Role.Name).ToList<string>();

            return roles.ToArray();
        }
    }
}

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

2 голосов
/ 09 февраля 2012

Проблема в контекстной ссылке.Когда вы создаете ссылку на контекст (EntityDB), из метода, который получает роли из вашего контекста, эти ссылки остаются такими же, другими словами, все выбранные вами данные будут одинаковыми, поскольку выбор будет сделанконтекст отсутствует в базе данных (это путь к тому, чтобы EF не шел все время к базе данных).Изменения, которые вы делаете (в ролях), были сделаны в другом контексте, поэтому для получения правильного контекста вам нужно создать новый экземпляр вашего контекста.Сделайте это внутри метода, используя клавиатуру, используя:

using (var database = new EntityDB())
{
    // Get your roles and return them
}
...