代码之家  ›  专栏  ›  技术社区  ›  si2030

asp.net core ef linq-我能分解一个大的查询语句并让它执行一次吗?

  •  1
  • si2030  · 技术社区  · 5 年前

    我一直觉得,如果我写下面的代码:

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

    它将执行将内容传递到filteredclients的语句,此时我希望使用where子句对许多列进行筛选。

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

    然后我遇到了 this answer from 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=_clientapiprepository.allincluding(s=>s.jobs,s=>s.urbane);
    

    然后,在方法的后面,我添加了一个 where 条款如下:

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

    …等等,在构建查询的基础上-根据选择了什么过滤器和orderby,我可以在我的方法中这样做。

    我想知道是否可以逐步构建查询,添加 哪里 条款和订单仅基于从网页发送的内容。并且,在执行查询时..如果执行一次或多次?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Matthew    5 年前

    是的,您可以逐步构建查询,而无需执行查询。我相信这个叫做 deferred execution . 基本上,针对数据源的LINQ查询创建一个 IQueryable<Type> 可以传递和修改的对象。这只是构建了一系列SQL命令,而不是获得实际结果。 然后,您可以通过调用以下函数之一来执行它: ToList , ToDictionary , FirstOrDefault , Average , Sum 等。列举 IQueryable (例如) foreach )也会导致它执行。只要查询的上下文没有被释放,就可以添加尽可能多的 where orderby 根据需要添加子句,并在完成后执行。 链接示例:

    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);
        }
    }