2016-08-02 9 views
0

У меня есть метод расширения, который нужно запросить базу данных для проверки прав доступа пользователей следующим образом:ASP MVC 5 Уничтожение контекста объекта

public static bool HasPermission(this IPrincipal user, string permission) 
{ 
    ApplicationUser appUser = ApplicationUserManager.GetUser(user.Identity.GetUserId()); 

    return appUser.HasPermission(permission); 

} 

В настоящее время вызов, чтобы получить пользователю приложения реализовано следующим образом:

public static ApplicationUser GetUser(string userId) 
{ 
     return GetUser(new ApplicationDbContext(), userId); 
} 

public static ApplicationUser GetUser(ApplicationDbContext context, string userId) 
{ 
     ApplicationUser _retVal = null; 
     try 
     { 
      _retVal = context.Users.Where(p => p.Id == userId).FirstOrDefault(); 
     } 
     catch (Exception) 
     { 
     } 

     return _retVal; 
} 

Теперь в моих представлениях и действиях контроллера я часто вызываю метод User.HasPermission(). Поэтому я рассматриваю влияние производительности на частое обращение к этому методу. Было бы лучше реализовать вызов, завершающий его внутри оператора using, как показано ниже, чтобы контекст удалялся, или я правильно понимаю, как я уже реализовал его выше?

public static bool HasPermission(this IPrincipal user, string permission) 
    { 
     using (ApplicationDbContext _context = new ApplicationDbContext()) 
     { 
      var userId = user.Identity.GetUserId(); 
      ApplicationUser applicationUser = _context.Users.Where(p => p.Id == userId).FirstOrDefault(); 
      return applicationUser.HasPermission(permission); 
     } 
    } 
+0

Сколько ApplicationUser существует в вашем db? Вы ожидаете, что это число увеличится или останется довольно похожим? Ваше приложение 'hasPermission' выглядит отлично, это гарантирует, что сборщик мусора уничтожит объект контекста в конце блока и освободит память. Однако, если вы проверяете разрешения для одного и того же пользователя снова и снова, возможно, стоит сохранить этот объект в памяти, а не постоянно повторно запрашивать базу данных. – gudthing

+0

@gudthing, поэтому нет необходимости обертывать его в используемый блок? Количество пользователей увеличится с 500 до 1000. – adam78

+0

@ gudthing, как вы собираетесь хранить его в памяти? Какой пример кода поможет проиллюстрировать? – adam78

ответ

0

Устранение вашего контекста db - хорошая идея. Я бы помещал контекст в класс-оболочку и обрабатывал специфические для приложения db-запросы с помощью определенных методов. например GetUser (id), GetAllItems(), GetSingleItem (id), GetItemsByCategory (категория) и т. Д. Использование C# generics, репозиториев и базовых классов может помочь в повторном характере этих типов вызовов, когда у вас много разных типов активов.

Это гарантирует, что ваш dbcontext вызывается и удаляется для каждого требуемого экземпляра. например

Об одном запросе страницы

  • GetUser (открытый отчуждать)
  • GetSomethingElse (открытый выбрасывайте РАЗ)
  • SaveSomething (открытый выбрасывайте РАЗ)

Кроме того, Я бы добавил полное разрешение пользователя, установленное непосредственно в класс User, когда оно загружено, вместо того, чтобы делать отдельные вызовы БД для каждого запроса «HasPermission».

Используйте механизм кэширования (то есть MemoryCache) для хранения этого пользовательского объекта вместе с их набором разрешений. Этот же механизм кеша можно использовать и для хранения данных приложения. Есть некоторые предварительно построенные там, если вы google вокруг, но настройка базового не сложна.

С кешированием пользователь запрашивает что-то с вашего сайта, и он уже знает, кто они и к чему у них есть доступ, даже не прикасаясь к БД (снова), по крайней мере, несколько минут, возможно, дольше, в зависимости от того, как часто разрешаются изменения. 5-15-минутный доступ к кеш-памяти довольно разумный. Методы удаления кеша могут обеспечить, чтобы набор разрешений всегда был точным, предполагая, что вы сами контролируете хранилище разрешений или имеете крючки, которые могут запускать обновления на вашем конце.