Entity Framework lambda 扩展方法在啥时候将查询发送到数据库?
Posted
技术标签:
【中文标题】Entity Framework lambda 扩展方法在啥时候将查询发送到数据库?【英文标题】:At what point does Entity Framework lambda extension method send the query to database?Entity Framework lambda 扩展方法在什么时候将查询发送到数据库? 【发布时间】:2019-06-18 17:30:03 【问题描述】:我试图弄清楚如何优化一些数据库查询,以便它们使用我们数据库中内置的索引,并快速提取所请求的数据。
我想了解的是,在下面的代码中,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);
【问题讨论】:
docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/… 是的,当您使用数据或执行 ToList() 或类似操作时。我认为前 2 个代码块可能是一个并且是相同的......就像 2 组带有 AND 的条件。 您可以执行第一个块,选择 shift_offers 的 ID,然后执行 ToList()。然后,在您的第二个块中添加一个条件,其中 ID 包含在上一个列表中。 @Romias - 我实际上需要做的是在第一个块之后做一个 ToList,然后在列表上的应用程序中做其余的事情。第一个代码块是索引优化的,所以即使在最坏的情况下它也能很快地提取数据。其余的不是,这就是我的查询卡住的原因。 是的,我认为我们在同一页上。 【参考方案1】:在以下情况下对数据库执行查询:
它由 foreach (C#) 或 For Each (Visual Basic) 枚举 声明。 由ToArray等集合操作枚举, ToDictionary 或 ToList。 在最外层指定了诸如 First 或 Any 等 LINQ 运算符 查询的一部分。 调用以下方法: DbSet、DbEntityEntry.Reload 和 Database.ExecuteSqlCommand。在您的情况下,当您调用 ToListAsync() 方法时。作为一般规则,只要您使用 IQueryable 对象,就不会执行查询,一旦您尝试将其强制转换为其他对象,就会进行查询。
来源:https://docs.microsoft.com/en-us/ef/ef6/querying/
【讨论】:
是的,我刚刚从 Adam 链接的文档中提取了它。太棒了。以上是关于Entity Framework lambda 扩展方法在啥时候将查询发送到数据库?的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework lambda 扩展方法在啥时候将查询发送到数据库?
如何使用 Entity Framework Core 2.0 上的 lambda 语法在 LINQ 中实现 LEFT OUTER JOIN?
MVC5 Entity Framework学习之Entity Framework高级功能
Entity Framework 学习系列 - 认识理解Entity Framework
Entity Framework Code-First(23):Entity Framework Power Tools