簡體   English   中英

使用.Skip(0)時,強制LINQ to SQL使用RowNumber()而不是Top n

[英]Force LINQ to SQL to use RowNumber() instead of Top n When Using .Skip(0)

有沒有一種方法可以使LINQ to SQL在使用Skip(0)時避免使用TOP X? 我有一個查詢,對於每個分頁結果都可以正常運行……除了第1頁。我已經對該查詢進行了概要分析,並且引入TOP子句只會殺死它。 我對為什么會這樣感到困惑,但事實確實如此。 但是,在1到10之間使用RowNumber可以正常工作。

有沒有一種方法可以使LINQ to SQL在使用Skip(0)時避免使用TOP X? 我有一個查詢,對於每個分頁結果都可以正常運行……除了第1頁。我已經對該查詢進行了概要分析,並且引入TOP子句只會殺死它。 我對為什么會這樣感到困惑,但事實確實如此。 但是,在1到10之間使用RowNumber可以正常工作。

罪魁禍首似乎是我的WHERE子句中的EXISTS條件。 產生的SQL在下面。 在SQL Manager中,此查詢運行良好,並返回14個結果...但是,一旦我添加了TOP 10,它就會超時(如LINQ那樣)。 但是,如果我在where子句中注釋EXISTS,那么問題就消失了。

SELECT 
    t0.ProtectiveOrderID, 
    t3.DocketID, 
    t3.DocketNumber AS CaseNumber, 
    t3.PartySuffix AS CaseNumberSuffix, 
    t5.FirstName AS RespondentNameFirst, 
    t5.MiddleName AS RespondentNameMiddle, 
    t5.LastName AS RespondentNameLast, 
    t5.NameSuffix AS RespondentNameSuffix,
    t4.FirstName AS ProtectedNameFirst, 
    t4.MiddleName AS ProtectedNameMiddle, 
    t4.LastName AS ProtectedNameLast, 
    t4.NameSuffix AS ProtectedNameSuffix, 
    t3.ChildNextFriendFirstName AS ChildNextFriendNameFirst, 
    t3.ChildNextFriendMiddleName AS ChildNextFriendNameMiddle, 
    t3.ChildNextFriendLastName AS ChildNextFriendNameLast, 
    t3.ChildNextFriendNameSuffix
FROM dbo.ProtectiveOrder AS t0
INNER JOIN (
SELECT MAX(t1.ProtectiveOrderID) AS value
FROM dbo.ProtectiveOrder AS t1
GROUP BY t1.DocketID
) AS t2 ON t0.ProtectiveOrderID = t2.value
LEFT OUTER JOIN dbo.Docket AS t3 ON t3.DocketID = t0.DocketID
LEFT OUTER JOIN dbo.Directory AS t4 ON t4.DirectoryID = t3.ProtectedPartyID
LEFT OUTER JOIN dbo.Directory AS t5 ON t5.DirectoryID = t3.SubjectID
WHERE 
(
    ((t4.LastName LIKE 'smith%') AND (t4.FirstName LIKE 'jane%')) 
    OR ((t5.LastName LIKE 'smith%') AND (t5.FirstName LIKE 'jane%')) 
    OR ((t3.ChildNextFriendLastName LIKE 'smith%') AND (t3.ChildNextFriendFirstName LIKE 'jane%')) 
    OR (
            -- ***************
            -- THIS GUY KILLS THE QUERY WHEN A TOP IS INTRODUCED IN THE TOP-LEVEL SELECT
            -- ***************
            EXISTS(
                    SELECT NULL AS EMPTY
                    FROM dbo.Child AS t6
                    WHERE (t6.LastName LIKE 'smith%') AND (t6.FirstName LIKE 'jane%') AND (t6.DocketID = t3.DocketID)
            )
    )
)
ORDER BY t3.DocketNumber

覆蓋“跳過”方法,僅檢查輸入是否為零。 對於除零以外的任何值,請調用原始的skip方法。 對於零不要。

因此,如果您修改dynamic.cs中提供的“跳過”,則可以執行以下操作:

    public static IQueryable Skip(this IQueryable source, int count)
    {
        if (count == 0)
        {
            return source;
        }
        if (source == null) throw new ArgumentNullException("source");
        return source.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Skip",
                new Type[] { source.ElementType },
                source.Expression, Expression.Constant(count)));
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM