Форум программистов, компьютерный форум, киберфорум
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
1

Получение юзера. FindByIdAsync или SingleOrDefaultAsync

20.07.2018, 10:01. Показов 1591. Ответов 14

Author24 — интернет-сервис помощи студентам
Добрый день!

Есть два способа получения юзера по идентификатору:

C#
1
var user = await _userManager.FindByIdAsync(id);
C#
1
var user = await _db.Users.AsNoTracking().SingleOrDefaultAsync(u => u.Id == id);
На всякий случай вот контроллер:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public class HomeController : Controller
{
    public HomeController(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
    {
        _db = context;
        _userManager = userManager;
    }
 
    private ApplicationDbContext _db;
    private UserManager<ApplicationUser> _userManager;
 
...
}
Какой из этих способов предпочтительнее и какой создает меньше нагрузку на процессор?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.07.2018, 10:01
Ответы с готовыми решениями:

Получение ID / LOGIN юзера и отправка в бд
Как получить ID / LOGIN юзера и посылать в бд, чтобы отображать состояние баланса юзера на сайте:...

Насколько точно скрипт в примере определит IP адрес юзера, агент юзера?
вот собственно сам скрипт: &lt;? $ip=false; if(isset($_SERVER) &amp;&amp; $_SERVER!='127.0.0.1' &amp;&amp;...

Загрузка изображения для профиля юзера в одном контроллере с загрузкой данных юзера
Алгоритм таков: 1. При добавлении клиента необходимо загрузить фото 2. Загружаю 3. Заполняю...

Как добавить в DirectoryEdit1.Text путь к папке юзера, если имя юзера кириллицей?
Делаю такDirectoryEdit1.Text:=GetEnvironmentVariable('USERPROFILE') выдает вопросительные знаки...

14
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 10:45 2
Serg34, вы могли бы сами замерять)

Очень странно, что у вас есть два пути получения пользователя. Если есть специальный сервис для работы с юзерами, то нужно работать через него, а не лезть в базу напрямую (вопрос здравого смысла, а не производительности).

А разница из этих двух подходов не очевидна, ибо не известно, что происходит в FindByIdAsync.

Добавлено через 6 минут
Но по-хорошему, разницы не должно быть. В методе FindByIdAsync может быть какая-то дополнительная логика или кеширование, но даже в этом случае, разница будет крошечно (если вообще будет заметна).

А вот корректность - вопрос уже другой. Если в FindByIdAsync действительно предусмотрена некая логика, то ходить мимо неё вы просто не имеете права.
1
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
20.07.2018, 10:57  [ТС] 3
Цитата Сообщение от Usaga Посмотреть сообщение
Serg34, вы могли бы сами замерять)
Да, но это будет всего лишь один замер))
Я если честно ожидал ответа вроде "Все зависит от ситуации. В одних случаях нужно так, в других так"

Цитата Сообщение от Usaga Посмотреть сообщение
Очень странно, что у вас есть два пути получения пользователя.
_userManager используется как минимум для получения активного пользователя:

C#
1
var user = await _userManager.GetUserAsync(User);
Но и еще дает дополнительную возможность получения других пользователей...

Цитата Сообщение от Usaga Посмотреть сообщение
А вот корректность - вопрос уже другой.
Да, думаю, надо FindByIdAsync использовать.
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 11:02 4
Цитата Сообщение от Serg34 Посмотреть сообщение
Да, но это будет всего лишь один замер))
Заверните вызов метода в цикл с парой тысяч итераций и замеров станет больше.

Добавлено через 38 секунд
Цитата Сообщение от Serg34 Посмотреть сообщение
Но и еще дает дополнительную возможность получения других пользователей...
А второй способ, принимающий ID пользователя, такой возможности не даёт?)
0
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
20.07.2018, 11:05 5
Цитата Сообщение от Serg34 Посмотреть сообщение
Какой из этих способов предпочтительнее и какой создает меньше нагрузку на процессор
Главное различие в том, что при использовании первого варианта запрос к базе будет произведен только в том случае, если в контексте уже не закэширован объект с эти Id (был загружен ранее).
Во втором случае запрос к базе будет производиться в любом случае, то есть всегда будет получена свежая информация в рамках текущей транзакции.

P.S. Я предполагаю, что UserManager в кишках использует метод Find.
2
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 11:09 6
Цитата Сообщение от kolorotur Посмотреть сообщение
Я предполагаю, что UserManager в кишках использует метод Find.
Но если контекст создаётся на каждый запрос, то кеш будет пуст.
1
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
20.07.2018, 11:12 7
Цитата Сообщение от Usaga Посмотреть сообщение
Но если контекст создаётся на каждый запрос, то кеш будет пуст.
Верно, но у ТСа контекст передаетя в конструктор контроллера и хранится в поле класса.
Подозреваю, что он может быть использован многократно за время жизни контроллера.
1
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
20.07.2018, 11:21  [ТС] 8
Цитата Сообщение от Usaga Посмотреть сообщение
кеш будет пуст
А когда очищается кэш?
Цитата Сообщение от kolorotur Посмотреть сообщение
время жизни контроллера
А когда заканчивается жизнь контроллера? Когда пользователь переходит в метод другого контроллера?
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 11:25 9
Цитата Сообщение от kolorotur Посмотреть сообщение
Подозреваю, что он может быть использован многократно за время жизни контроллера.
По-хорошему, нет. Один запрос - один вызов метода.

Цитата Сообщение от Serg34 Посмотреть сообщение
А когда очищается кэш?
Кеш объектов хранится внутри контекста. Контекст создаётся на каждый запрос заново.

Цитата Сообщение от Serg34 Посмотреть сообщение
А когда заканчивается жизнь контроллера?
Когда заканчивается обработка запроса.
1
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
20.07.2018, 16:22  [ТС] 10
Цитата Сообщение от Usaga Посмотреть сообщение
вы могли бы сами замерять)
Думаю, это будет интересно: у меня получилось примерно в тысячу раз разница:
Получение юзера. FindByIdAsync или SingleOrDefaultAsync

Пробовал еще при помощи профилировщика производительности мерять, но он явно врал: 8 против 1500 мс, и второй способ явно больше полутора секунд длился.
Или я что не так замерил...
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 16:31 11
Serg34, значит метод FindByIdAsync кеширует запись и в базу ходит только один раз. Ещё учитывайте, что во втором случае создаётся делегат с лямбдой на каждой итерации, что тоже даёт некий оверхед накапливающийся с каждой итерацией.

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

Если вы испытываете проблемы с производительностью, то совершенно не там ищете причину.
0
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
20.07.2018, 16:51  [ТС] 12
Usaga, Да, проблемы с производительностью, наверно, больше связаны с кривыми руками.
А сейчас я в общеобразовательных целях все это исследую.
Про профилировщик было странно - почему он такие данные выдавал и можно ли ему верить...
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 16:55 13
Serg34, смотря как и что вы им замеряли... Если речь о времени затрачиваемы CPU на ваше приложение, то имейте в виду, что операции ввода-вывода (сеть, диски, работа с железом) в показания профилировщика не попадают, ибо в это время ваше приложение ждёт и ничего не делает.

А вы уже наблюдаете сумму этих задержек: работа CPU + ожидание данных от СУБД.
0
100 / 100 / 33
Регистрация: 20.09.2014
Сообщений: 457
Записей в блоге: 3
20.07.2018, 17:05  [ТС] 14
Usaga, перепутал: не профилировщик производительности, а сообщение справа от кода во время отладки.
Получение юзера. FindByIdAsync или SingleOrDefaultAsync

Насколько я понимаю, оно показывает именно время работы, включая всё, даже остановку выполнения.
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
20.07.2018, 17:09 15
Serg34, да, эта штука просто замеряет время выполнения, не различая на что оно ушло.
0
20.07.2018, 17:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.07.2018, 17:09
Помогаю со студенческими работами здесь

проблема Акцесс или юзера?
Подскажите уважаемые плз.. Перестали работать в коде такие вещи как Time(), Forms!и наверное...

Что лучше для юзера i7 3770 или Intel Xeon E5 1650?
Сейчас i5 2400 и RX 570 4 Gb (да, проц ее не вытаскивает вообще). Уже месяц не могу начать...

Работа с процессами или активными окнами (получение окна или хэндла)
Доброго времени суток народ!!! Есть такая проблема вообщем не знаю как даже оформить вопрос вообщем...

Получение или изменение SteamID
Здрасти... Играю на пиратки Rust и пишу лаунчер для сервера. Сейчас стоит задача поменять на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru