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它在外面
我有一个查询,我将提供相关部分
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它在外面