Entity Framework lambda 扩展方法在什么时候将查询发送到数据库?
At what point does Entity Framework lambda extension method send the query to database?
我正在尝试弄清楚如何优化某些数据库查询,以便它们使用我们数据库中内置的索引,并快速提取所请求的数据。
我想了解的是,在下面的代码中,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);
在以下时间对数据库执行查询:
- 它由foreach (C#) 或For Each (Visual Basic) 枚举
声明。
- 通过ToArray等集合操作枚举,
ToDictionary 或 ToList.
- 在最外层指定了 First 或 Any 等 LINQ 运算符
查询的一部分。
- 调用了以下方法:加载扩展方法
DbSet、DbEntityEntry.Reload 和 Database.ExecuteSqlCommand.
您的情况是调用 ToListAsync() 方法时。作为一般规则,只要您使用 IQueryable 对象,就不会执行查询,一旦您尝试将其转换为其他对象,就会进行查询。
我正在尝试弄清楚如何优化某些数据库查询,以便它们使用我们数据库中内置的索引,并快速提取所请求的数据。
我想了解的是,在下面的代码中,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);
在以下时间对数据库执行查询:
- 它由foreach (C#) 或For Each (Visual Basic) 枚举 声明。
- 通过ToArray等集合操作枚举, ToDictionary 或 ToList.
- 在最外层指定了 First 或 Any 等 LINQ 运算符 查询的一部分。
- 调用了以下方法:加载扩展方法 DbSet、DbEntityEntry.Reload 和 Database.ExecuteSqlCommand.
您的情况是调用 ToListAsync() 方法时。作为一般规则,只要您使用 IQueryable 对象,就不会执行查询,一旦您尝试将其转换为其他对象,就会进行查询。