Преобразует ли IQueryable в IEnumerable снова запрос?

В моем запросе мне нужно вернуть IEnumerable, но я не знаю, приведет ли это действие к выполнению запроса снова?

var data = Repository<Person>.Find().AsEnumerable();

Find() возвращает IQueryable и потому, что IQueryable наследует IEnumerable. Я сомневаюсь, что AsEnumerable выполняет повторное выполнение.

Я знаю, что var data = Repository<Person>.Find().ToList() выполняет запрос два раза. Один для Find() и второй для Tolist()

Ответы

Ответ 1

IQueryable - это IEnumerable. Нет никакого преобразования, и поэтому никакой работы не происходит.

Работа происходит, когда вы вызываете GetEnumerator(), либо явно, либо вызывая foreach на нем.

Кроме того, подтвердили ли вы, что Repository.Find().ToList() дважды вызывает SQL? Мне это не кажется правильным.

Ответ 2

AsEnumerable фактически ничего не делает, кроме применения оператора as к вашему IQueryable. Соответственно, любой будущий метод, который вы применяете к вашему объекту, будет использовать набор методов расширения System.Linq.Enumerable в отличие от методов System.Linq.Queryable.

Это все о отсроченном исполнении. Ничто никогда не будет выполнено против вашего запрашиваемого источника (предположительно базы данных), пока вы не попытаетесь перечислить.

Другими словами:

var data=Repository.Find().AsEnumerable() 
/* The query is only actually performed AFTER here */  
.ToList();

Если ваш код:

var data=Repository.Find().ToList();

выполняет запрос два раза, потому что вы делаете что-то неправильное в вашем методе Find(), что определенно не должно быть.

var data = Respository.Find();

должен выполнить запрос ZERO раз.

var result = data.ToList(); // THIS is what should execute the query.

Ответ 3

думать о linq как о "потоке", а агрегатная функция - "Flush". поток "linq to db" может только один раз промываться. .AsEnumerable(),.Where(),.... является способом подготовки запроса .ToList(),.First(),.Max() - это совокупность но если вы не вызываете агрегат, тогда ваш результат linq не будет запущен. его начало работать только при его перечислении.

ех

var result = users.Select(usr => usr.Name);

ничего не произойдет здесь, пока

1 агрегат называется

result.First()

или 2 результат перечисляется

result.ToList().ForEach(...)

чтобы ответить на ваш вопрос -.Find(),.AsEnumerable() не является агрегированной функцией