Linq-to-sql 使用 GroupBy 和 return 记录满足条件

Linq-to-sql using GroupBy and return record satisfying condition

我有一个查询,我将提供相关部分

IQueryable<a> query;

query.Where(dbEntry => dbEntry.ConditionId == id)
    .Where(dbEntry => dbEntry.PharmacyStockBBD.Value > NO_BEFORE_THAN)
    .GroupBy(dbEntry => dbEntry.ProductId, pair => pair, (_e1, _e2) => new
    {
        ProductId = _e1,
        Entry = _e2.OrderBy(pair => pair.PharmacyStockBBD).First()
    })
    .ToListAsync();

我得到

System.InvalidOperationException: The LINQ expression '(GroupByShaperExpression:
KeySelector: (p.Id), 
ElementSelector:new { 
    PharmacyStockId = (ProjectionBindingExpression: PharmacyStockId), 
    PharmacyStockBBD = (ProjectionBindingExpression: PharmacyStockBBD), 
    ProductId = (ProjectionBindingExpression: ProductId), 
    ProductName = (ProjectionBindingExpression: ProductName), 
    ChildProductId = (ProjectionBindingExpression: ChildProductId), 
    IcnId = (ProjectionBindingExpression: IcnId), 
    IcnName = (ProjectionBindingExpression: IcnName), 
    PharmacyStock_ProductBoxes = (ProjectionBindingExpression: PharmacyStock_ProductBoxes), 
    .....
 }
)
    .OrderBy(pair => pair.PharmacyStockBBD)' could not be translated. Either rewrite the query in a form that can be translated,

or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

我想做的是按 ProductId 分组,但只获取 PharmacyStockBBD 为 Min 的记录。

我已经准备好了

Entry = _e2.Min(pair => pair.PharmacyStockBBD)

有效,但我需要整个 _e2。

我还知道 GroupBy 将在 sql 引擎 (MSSSQL) 上执行,我也知道它需要一些聚合函数,但我需要 PharmacyStockBBD 的整个记录​​集分钟

我认为最有效的方法是使用原始 sql;

    context.YourTable.FromSqlInterpolated(@"
SELECT * 
FROM
(
  SELECT *, ROW_NUMBER() OVER(PARTITION BY ProductId ORDER BY PharmacyStockBBD) rn
  FROM YourTable
  WHERE 
    PharmacyStockId > {NO_BEFORE_THAN}
) x
WHERE rn = 1")

您可以在此基础上进行创作(包括更多表格等

我不确定你想在哪里做 ConditionId 检查;它的确有所作为。如果您在内部查询中执行此操作,那么您将找到该条件下的所有产品,然后从 1 开始对它们进行编号并找到该条件下的最小产品。如果您在外部查询中执行此操作,您将找到所有产品而不考虑条件,对它们进行编号,然后丢弃所有不符合条件的产品。你放在哪里取决于第一个产品是否是你想要的状态

本质上,你是想“filter for condition, then take the first” -> 放在里面where,还是你想“take all the firsts, then filter them for condition” -> put它在外面