【问题标题】:EF Core applying TOP (x) in the wrong place - Take and OrderByEF Core 在错误的地方应用 TOP (x) - Take and OrderBy
【发布时间】:2019-01-24 22:54:18
【问题描述】:

我使用的是 EF Core 2.1,生成的 SQL 查询是错误的,因为它在错误的位置应用了 TOP(x)。

这是 EF 核心:

            IQueryable<OfferRequest> query = dbContext.OfferRequests;
            if (includes != null)
            {
                query = includes(query);
            }
            if (offerProgressStageId.HasValue)
            {
                query = query.Where(p => p.OfferProgressStageId == offerProgressStageId.Value);
            }
            if (offerStageId.HasValue)
            {
                query = query.Where(p => p.OfferStageId == offerStageId.Value);
            }
            if (isRelatedToStage)
            {
                query = query.Where(p => p.OfferStageId != null);
            }
            else
            {
                query = query.Where(p => p.OfferProgressStageId == null);
            }

            query = query.Where(p => p.OfferId == offerId && p.IsActive);

            if (maxCount.HasValue)
            {
                query = query.Take(maxCount.Value);
            }



            return query.OrderBy(p => p.RequestStatusId).ThenByDescending(p => p.RequestType.DisplayNumber).ToList();

这是生成的 SQL:

declare @__p_1 int = 50, @__offerId_0 int = 1

SELECT [t].[OfferRequestId], [t].[DateCreated], [t].[DateUpdated], [t].[EndDate], [t].[EndUserId], [t].[EventBlock], [t].[IsActive], [t].[IsSpecificToOfferProgressStage], [t].[Message], [t].[OfferId], [t].[OfferProgressStageId], [t].[OfferStageId], [t].[OfferRequestProgressId], [t].[RequestStatusId], [t].[RequestTypeId], [t].[StartDate], [t].[StartUserId], [t].[UserId], [p.RequestType].[RequestTypeId], [p.RequestType].[AllowsFreeText], [p.RequestType].[DateCreated], [p.RequestType].[DateUpdated], [p.RequestType].[Description], [p.RequestType].[DisplayNumber], [p.RequestType].[IsActive], [p.RequestType].[IsMain], [p.RequestType].[ShortDescription], [p.RequestType].[UserId]
FROM (
    SELECT TOP(@__p_1) [p].[OfferRequestId], [p].[DateCreated], [p].[DateUpdated], [p].[EndDate], [p].[EndUserId], [p].[EventBlock], [p].[IsActive], [p].[IsSpecificToOfferProgressStage], [p].[Message], [p].[OfferId], [p].[OfferProgressStageId], [p].[OfferStageId], [p].[OfferRequestProgressId], [p].[RequestStatusId], [p].[RequestTypeId], [p].[StartDate], [p].[StartUserId], [p].[UserId]
    FROM [OfferRequest] AS [p]
    WHERE [p].[OfferProgressStageId] IS NULL AND (([p].[OfferId] = @__offerId_0) AND ([p].[IsActive] = 1))
) AS [t]
INNER JOIN [RequestType] AS [p.RequestType] ON [t].[RequestTypeId] = [p.RequestType].[RequestTypeId]
ORDER BY [t].[RequestStatusId], [p.RequestType].[DisplayNumber] DESC

EF 也抱怨,因为我在没有 ORDER BY 的情况下执行 TOP(x),但那是因为它以错误的方式生成 SQL。

【问题讨论】:

  • 其实你在错误的地方申请Take。它应该在之后 OrderBy / ThenBy
  • 这正是我在玩查询时发现的。感谢您花时间分析它。如果您想提交答案,我将删除我的并接受您的。

标签: entity-framework-core


【解决方案1】:

我通过稍微更改 LINQ 查询解决了这个问题。当你有一个 Take 和一个 OrderBy 时,首先调用 OrderBy 然后 Take 是很重要的。

            IQueryable<OfferRequest> query = dbContext.OfferRequests;
            if (includes != null)
            {
                query = includes(query);
            }
            if (offerProgressStageId.HasValue)
            {
                query = query.Where(p => p.OfferProgressStageId == offerProgressStageId.Value);
            }
            if (offerStageId.HasValue)
            {
                query = query.Where(p => p.OfferStageId == offerStageId.Value);
            }
            if (isRelatedToStage)
            {
                query = query.Where(p => p.OfferStageId != null);
            }
            else
            {
                query = query.Where(p => p.OfferProgressStageId == null);
            }

            query = query.Where(p => p.OfferId == offerId && p.IsActive);

            query = query.OrderBy(p => p.RequestStatusId).ThenByDescending(p => p.RequestType.DisplayNumber);

            if (maxCount.HasValue)
            {
                query = query.Take(maxCount.Value);
            }

            return query.ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 2011-07-16
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多