是否可以将小查询组合成单个查询?

Is it possible to combine small queries into single query?

我有以下疑问:

var truckCount = await DbContext.Trucks
    .Where(t => t.Departure == null)
    .CountAsync();

var firstTruck = await DbContext.Trucks
    .Where(t => t.Departure == null)
    .MinAsync(t => t.Arrival);

var railcarCount = await DbContext.Railcars
    .Where(r => r.Departure == null)
    .CountAsync();

var firstRailcar = await DbContext.Railcars
    .Where(t => t.Departure == null)
    .MinAsync(t => t.Arrival);

任何人都可以告诉我是否可以将这些查询合并为一个,以便只有一次往返数据库?

我希望生成类似这样的查询。

select
    (select count(*) from Trucks where Departure is null) as TruckCount,
    (select min(Arrival) from Trucks where Departure is null) as FirstTruck,
    (select count(*) from Railcars where Departure is null) as RailcarCount,
    (select min(Arrival) from Railcars where Departure is null) as FirstRailcar

我的后端是 SQL 服务器。

linq 不行,不行。为什么?因为两个原因:

  1. 查询语法无法获取计数并使用联合从一个查询中获取
  2. 方法计数,立即执行而不延迟,所以你不能链接到一个查询中

老实说,即使使用 sql 查询也很难实现,因为数据具有不同的数据类型和列。

您需要使用第三方库,它可以在一次数据库往返中执行多个查询。也许 this extension 将来的查询适合您。

否则你可以实现一个 stored-procedure 来封装查询(作为子查询)和 returns 所需的信息。

另一种选择可能是只使用 2 个查询而不是 4 个:

var truckInfo = await DbContext.Trucks
    .GroupBy(t => t.Departure == null)
    .Where(g => g.Key == true)
    .Select(g => new { Count = g.Count(), FirstTruck = g.Min(t => t.Arrival) })
    .FirstOrDefaultAsync() ?? new { Count = 0, FirstTruck = DateTime.MinValue };

   // same for Railcars

以防万一,有 EF Core 扩展 linq2db.EntityFrameworkCore(请注意,我是创建者之一)可以 运行 此查询和几乎所有 SQL ANSI 查询LINQ

using var db = DbContext.CreateLinqToDBConnection();

var trucks = DbContext.Trucks
    .Where(t => t.Departure == null);

var railcars = DbContext.Railcars
    .Where(r => r.Departure == null);

var result = await db.SelectAsync(() => new 
{
    TruckCount = trucks.Ccount(),
    FirstTruck = trucks.Min(t => t.Arrival),
    RailcarCount = railcars.Count(),
    FirstRailcar = railcars.Min(t => t.Arrival)
});