2015-12-19 25 views
0

我試圖在我的ServiceStack(4.0.50)服務中完成分頁,並且當 查詢有多個連接 使用LoadSelect時我遇到問題。用LoadSelect分頁在SQL Server上的ServiceStack OrmLite失敗

爲了篩選安全要求的結果,我Get方法從一個自定義的用戶會話拉信息並生成一個查詢。類似這樣的:

public QueryResponse<Foo> Get(Foos request) 
{ 
    var session = SessionAs<CustomUserSession>(); 

    var q = Db.From<Foo>().LeftJoin<Foo, User>((s, u) => s.UserId == u.Id); 

    // Also tried this with no success 
    //q.Skip(request.Skip); 
    //q.Take(request.Take); 
    q.Limit(request.Skip, request.Take); 

    // I do filtering based on the request object for searching 
    if (request.Price.HasValue) 
    { 
     q.And(s => s.Price == request.Price); 
    } 
    // ... and so on ... 

    // Then I do filtering based on roles 
    if (session.HasRole("OrgAdmin")) 
    { 
     // Do some filtering for their organization 
    } 
    else if (session.HasRole("SiteManager")) 
    { 
     // More filtering here 
    } 

    // Ordering also... 
    if (request.OrderBy.IsNullOrEmpty()) 
    { 
     q.OrderByFieldsDescending(request.OrderByDesc); 
    } 
    else 
    { 
     q.OrderByFields(request.OrderBy); 
    } 

    var response = new QueryResponse<Foo> 
    { 
     // This works fine 
     Total = (int)Db.Count(q), 
     // === Error here === 
     Results = Db.LoadSelect(q) 
    }; 

    return response; 
} 

計數總是正常工作,並且結果的第一頁始終有效。但是,拉動後續頁面的結果會得到以下錯誤:當子查詢未與EXISTS一起引入時,只能在選擇列表中指定一個表達式。

不幸的是,我需要應用過濾,這就要求加入。 不幸的是我需要加載引用,並希望避免選擇n + 1的情況。我試着檢查q對象中的SQL表達式,但看起來好像沒有辦法看到發送給服務器的真正的最終SQL是什麼。

有什麼建議嗎?

注:我沒有使用自動查詢,我只是挪用了QueryBase<>QueryResponse<>對象使用尋呼和計算性能。

+0

看一看[這個問題](http://stackoverflow.com/questions/1904314/only-one-expression-can-be-specified-in-the-select-list-when-the-subquery-不是)。這可能是子查詢中有多個列。你真的需要知道生成了什麼SQL。 – Quantumplate

+0

不幸的是,我不認爲這是可能的,除非我使用ServiceStack源並嘗試調試它,而我不想這麼做。 –

+0

通常有一種方法!你可以用wireshark來檢查數據包嗎? http://internationaldatascience.com/using-wireshark-to-viewtrack-sql-server-browser-traffic/或者在SQL Server中記錄一些日誌?對不起,我不熟悉ServiceStack,所以不知道它是如何工作的。 – Quantumplate

回答

2

事實證明,這是與標準SqlServerDialect.Provider一個問題。由於這是SQL 2012,當我在AppHost中切換到SqlServer2012Dialect.Provider時,它按預期工作。

+0

順便說一句,你可以知道使用Db.GetLastSql()生成的SQL(放置try ... catch塊並在catch中調用Db.GetLastSql())。 – labilbe

+0

問題是由於SQL Server 2012之前生成的SQL無法使用便於SQL生成的LIMIT語句。在SQL Server 2008之前,必須使用複雜的SQL語法來完成這項工作。 – labilbe