首页 > 解决方案 > Entity Framework lambda 扩展方法在什么时候将查询发送到数据库?

问题描述

我试图弄清楚如何优化一些数据库查询,以便它们使用我们数据库中内置的索引,并快速提取请求的数据。

我想了解的是,在下面的代码中,什么时候将 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);

标签: c#entity-frameworkasp.net-mvc-5extension-methods

解决方案


在以下情况下对数据库执行查询:

  • 它由 foreach (C#) 或 For Each (Visual Basic) 语句枚举。
  • 它由集合操作枚举,例如 ToArray、ToDictionary 或 ToList。
  • LINQ 运算符(如 First 或 Any)在查询的最外层部分指定。
  • 调用以下方法:DbSet、DbEntityEntry.Reload 和 Database.ExecuteSqlCommand 上的 Load 扩展方法。

在您的情况下,当您调用 ToListAsync() 方法时。作为一般规则,只要您使用 IQueryable 对象,就不会执行查询,一旦您尝试将其投射到其他对象上,就会进行查询。

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


推荐阅读