ASP.NET 核心 EF LINQ - 是否可以分解大型查询语句并仍执行一次



我一直觉得如果我编写以下代码:

filteredClients = _clientAPIRepository.AllIncluding(s => s.Jobs, s => s.Suburb);

它将执行将内容传递到 filteredClients 的语句,此时我想使用 where 子句过滤许多列。

我最初的理解是它将整个表转移到内存中,而不是在数据库服务器上完成所有工作。我对这里的效率感兴趣,并希望在数据库上执行一次查询,而不必返回,因为我添加了 where 子句等。所以我试图创建一个大的一次性语句来尝试满足这个意图,但是......

然后,我从 Jon Skeet 那里看到了这个答案,表明在您开始使用结果之前,EF 查询不会立即执行。

我处于我不知道查询形状的位置......这个人可以过滤一列或几列,也可以对一列或几列进行排序。

如前所述,我尝试使用单个查询进行过滤,同时尝试考虑到以下不需要某些 where 子句的事实。

filteredClients = _clientAPIRepository.AllIncluding(s => s.Jobs, s => s.Suburb)
.Where(c => c.ClientNo.ToString().StartsWith(clientFilters.ClientNo) || clientFilters.ClientNo == string.Empty)
.Where(c => c.CompanyName.StartsWith(clientFilters.ClientLastName) || clientFilters.CompanyName == string.Empty)
.Where(c => c.MobilePhone.StartsWith(clientFilters.MobilePhone) || clientFilters.MobilePhone == string.Empty);

..我还需要为此添加排序。

如果我从这个查询开始(使用谓词(:

filteredClients = _clientAPIRepository.AllIncluding(s => s.Jobs, s => s.Suburb);

然后,在该方法的稍后,我向其添加了一个where子句,如下所示:

filteredClients.where.Where(c => c.ClientNo.ToString().StartsWith(clientFilters.ClientNo));

..依此类推建立查询 - 基于我可以选择的过滤器和排序,我可以在我的方法中执行。

我想知道我是否可以逐步构建查询,仅根据从网页发送的内容添加where子句和排序。并且,当执行查询时。并且,如果它执行一次或多次?

是的,您可以逐步构建查询,而无需执行它们。我认为这称为延迟执行。基本上,针对数据源的 Linq 查询会创建一个可以传递和修改的IQueryable<Type>对象。这只会构建一堆SQL命令,而不是获得实际结果。 然后你可以通过调用其中一个函数来执行它,如ToListToDictionaryFirstOrDefaultAverageSum等。枚举IQueryable(例如foreach( 也会导致它执行。因此,只要您查询的上下文未释放,您就可以根据需要添加任意数量的whereorderby子句,并在完成后执行它。 链接中的示例:

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
IQueryable<Product> productsQuery =
from p in context.Products
select p;
IQueryable<Product> largeProducts = productsQuery.Where(p => p.Size == "L");
Console.WriteLine("Products of size 'L':");
foreach (var product in largeProducts) // <-- Query is not executed until here
{
Console.WriteLine(product.Name);
}
}

最新更新