#c# #automapper
Вопрос:
Я не знаю, в чем проблема, я использую шаблон репозитория в запросе API, вот код
В Хранилище
public IQueryable<IUser> Get()
{
return _mapper.Map<IQueryable<IUser>>(_context.Users.AsQueryable());
}
В API
// GET: api/UserEntities
public IQueryable<UserEntity> GetUsers()
{
return _mapper.Map<IQueryable<UserEntity>>(_repository.Get());
}
Комментарии:
1. какой тип _context. Пользователи ?
2. О, я поставил _context. Пользователи. Запрашивается()
3. @viveknuna Я пытался дозвониться, но получил тот же ответ
4. Куда ты делась
.ToList()
?5. Вместо AsQueryable()
Ответ №1:
Давайте начнем с основ. Этот фрагмент кода:
public IQueryable<IUser> Get()
{
return _mapper.Map<IQueryable<IUser>>(_context.Users.AsQueryable());
}
это совершенно неправильно во многих отношениях:
- Тебе не следует возвращаться
IQueryable<T>
. Это приводит к утечке зависимости Entity Framework. - Вы должны запускать картограф не против an
IQueryable<T>
, а скорее против элементов результата. - Выполнение
AsQueryable()
на anIQueryable<T>
-это то же самое, что выполнение"string".ToString()
— > никакого эффекта, вообще. - Изменение
AsQueryable()
дляAsEnumerable()
вернет всю таблицу синхронно.
Даже если это просто для учебных целей, это совершенно неправильно, и вы просто изучаете ужасно неправильные методы. Лучше всего научиться делать все правильно с самого начала.
Поскольку вы используете Entity Framework, и очевидно, что утечка зависимости не является проблемой, давайте избавимся от всего этого метода и сделаем это правильно:
// GET: api/UserEntities
public async Task<IEnumerable<UserEntity>> GetUsersAsync()
{
var users = await _context.Users
.Select(x => _mapper.Map<UserEntity>(x))
.AsNoTracking()
.ToArrayAsync();
return users;
}
Entity Framework реализует шаблоны единиц работы и репозиториев, поэтому размещение его в другом репозитории-пустая трата времени, которая только усложняет работу без дополнительной выгоды, за исключением редких случаев, когда удаление EF является реальным вариантом.
Комментарии:
1. Я изучаю и использую шаблоны репозиториев, потому что я получу максимальное количество баллов за архитектуру, а также, если мне придется перейти с EF на что-то другое, это будет намного проще. Но спасибо за ваш ответ, помощь и желание научить меня чему-то. Хорошего дня
Ответ №2:
Вот как я просто исправил это В Репозитории
public IQueryable<IUser> Get()
{
return _mapper.Map<List<IUser>>(_context.Users).AsQueryable();
}
В API
public IQueryable<UserEntity> GetUsers()
{
return _mapper.Map<List<UserEntity>>(_repository.Get()).AsQueryable();
}
Комментарии:
1. Это неправильно ! An
IQueryable<T>
представляет собой запрос к внешней системе, который еще не выполнен , в то время как у вас уже есть список данных в памяти. Что касается Контроллера, контроллеры никогда не должны возвращатьсяIQueryable<T>
, что может иметь множество непредвиденных последствий, таких как многократное выполнение одного и того же запроса.