В какой момент метод лямбда-расширения Entity Framework отправляет запрос в базу данных? - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь выяснить, как оптимизировать некоторые запросы к базе данных, чтобы они использовали индексы, встроенные в нашу базу данных, и быстро извлекали запрашиваемые данные.

Что я хотел бы понять, так это то, в какой момент следующего кода IQueryable преобразуется в SQL и отправляется в базу данных для извлечения. Моя попытка ниже - попытаться использовать существующие индексы для сужения набора данных, а затем выполнить дополнительные более сложные и менее индексированные операции с меньшим набором данных.

Мой инстинкт заключается в том, что вызов на самом деле не идет в базу данных, пока я не вызову ToListAsync () (что делает мой подход ниже несколько бессмысленным), но я не уверен.

Для контекста приведенный ниже код является действием контроллера и заключен в некоторую обработку исключений. Ради простоты снял все это.

                var shift_Offers = db.Shift_Offers.Include(c => c.Callout)
                                                    .Where(x => x.Callout.shift_date_new >= today
                                                        && x.employee_id_fk == id
                                                        && x.offer_timestamp != null);

                //do the complex work on the data set once we've gotten the main dataset
                shift_Offers = shift_Offers.Where(x => ((x.Callout.employee_id_fk ?? -1) == id ||
                                                            (x.Callout.employee_id_fk ?? -1) == -1)
                                                        && (x.Callout.status.Contains(CalloutStatus.inprogress)
                                                            || x.Callout.status.Contains(CalloutStatus.inprogressWaitingNext)
                                                            || x.Callout.status.Contains(CalloutStatus.stopped)
                                                            || x.Callout.status.Contains(CalloutStatus.finishedSucceeded)
                                                            || x.Callout.status.Contains(CalloutStatus.finishedFailed)));

                //do work on the shift offer table last, once the data set is smallest
                shift_Offers = shift_Offers.Where(x => !x.offer_status.Contains(ShiftOfferStatus.NotYetOffered));

                Debug.WriteLine(shift_Offers.AsQueryable().ToString());
                List<Shift_Offer> shos = await shift_Offers.ToListAsync();
                return View(shos);

1 Ответ

0 голосов
/ 25 января 2019

Запрос выполняется к базе данных, когда:

  • Перечисляется с помощью оператора foreach (C #) или For Each (Visual Basic).
  • Перечисляется с помощьюОперация коллекции, такая как ToArray, ToDictionary или ToList.
  • Операторы LINQ, такие как First или Any, указываются в самой внешней части запроса.
  • Вызваны следующие методы: метод расширения загрузкидля DbSet, DbEntityEntry.Reload и Database.ExecuteSqlCommand.

В вашем случае, когда вы вызываете метод ToListAsync ().Как правило, пока вы работаете с объектами IQueryable, запрос не будет выполнен, как только вы попытаетесь привести его к чему-то другому, запрос будет выполнен.

source: https://docs.microsoft.com/en-us/ef/ef6/querying/

...