Я использую шаблон репозитория для доступа к данным с помощью Entity Framework и LINQ в качестве основы реализации нетестового репозитория. Большинство образцов, которые я вижу, возвращают AsQueryable(), когда вызов возвращает N записей вместо List <T> . В чем преимущество этого?
Зачем использовать AsQueryable() вместо List()?
Ответ 1
AsQueryable просто создает запрос, инструкции, необходимые для получения списка. Вы можете внести дальнейшие изменения в запрос позже, например добавить новые предложения Where, которые отправляются до уровня базы данных.
AsList возвращает фактический список со всеми элементами в памяти. Если вы добавите к нему новое предложение Where, вы не получите быструю фильтрацию базы данных. Вместо этого вы получаете всю информацию в списке, а затем отфильтровываете то, что вам не нужно в приложении.
Итак, в основном это сводится к ожиданию до последнего возможного момента, прежде чем совершить себя.
Ответ 2
Возврат IQueryable<T>
имеет то преимущество, что выполнение деффер, пока вы действительно не начнете перечислять результат, и вы можете составить запрос с другими запросами и все равно выполнить выполнение на стороне сервера.
Проблема заключается в том, что вы не можете контролировать время жизни контекста базы данных в этом методе - вам нужен открытый контекст и он должен оставаться открытым до тех пор, пока запрос не будет выполнен. И тогда вы должны убедиться, что контекст будет удален. Если вы вернете результат как List<T>
, T[]
или что-то подобное, вы потеряете дефферентное выполнение и выполнение на стороне сервера составленных запросов, но вы получите контроль над временем жизни контекста базы данных.
То, что подходит лучше всего, конечно, зависит от реальных требований. Это еще один вопрос без единой истины.
Ответ 3
AsQueryable
- это метод расширения для IEnumerable<T>
, который может выполнять две вещи:
- Если
IEnumerable<T>
реализуетIQueryable<T>
justs casts, ничего не делая. - В противном случае создается "поддельный"
IEnumerable<T>
(EnumerableQuery<T>
), который реализует каждый метод компиляции lambdas и вызов методов Enumerable extension.
Таким образом, в большинстве случаев использование AsQueryable бесполезно, если только вы не вынуждены передавать IQueryable методу, и вместо этого у вас есть IEnumerable, это взломать.
ПРИМЕЧАНИЕ. AsQueryable - это взлом, IQueryable, конечно же, не!
Ответ 4
Возврат IQueryable<T>
отсрочит выполнение запроса до тех пор, пока его результаты не будут использованы. До тех пор вы также можете выполнять дополнительные операции с запросами базы данных на IQueryable<T>
; на List
вы ограничены, как правило, менее эффективными операциями с оперативной памятью.