2011-07-30 30 views
0

爲了舉例,我刪除了非查詢和非必要的數據,只是爲了弄清楚如何在這裏執行初始查詢。與特定的未來<T>與nHibernate的查詢和集合有困難。

我有這樣的模型結構。

class Path { 
    Guid Id { get; protected set; } 
    IList<Step> Steps { get; set; } 
    void AddStep(Step entity) { 
    // write up bidirectional association 
    } 
} 
class Step { 
    Guid Id { get; protected set; } 
    Path Path { get; set; } 
    // other data irreleveent 
} 

現在假設50000步,每5000步......我不知道,我不希望一次返回所有的人。但限制我的查詢獲取並不是我真正的問題。

下面是我嘗試使用的確切查詢。我得到異常..

NHibernate.QueryException:重複別名:lpStep ----> System.ArgumentException:具有相同鍵的項已被添加。

我不完全確定如何處理這種情況。如果我在Path查詢中使用了Fetch,我得到了NHibernate Profiler的Select+N錯誤。

我的批處理啓用 - 但據我所知,這隻適用於插入,而不是檢索。但在任何情況下,我都會收回這些錯誤,並不確定如何處理它。有任何想法嗎?

using (var Transaction = Session.BeginTransaction()) { 

       Path lpPath = null; 
       Step lpStep = null; 

       var lpPaths = Session.QueryOver<Path>(() => lpPath) 
        .Take(50) 
        .Future<Path>(); 

       var lpSteps = Session.QueryOver<Step>(() => lpStep) 
        .JoinAlias(() => lpPath.Steps,() => lpStep) 
        .Where(o => o.Path.Id == lpPath.Id) 
        .Take(12) 
        .Future<Step>(); 

       Transaction.Commit(); 

       foreach (var path in lpPaths) { 
        Console.WriteLine("{0} fetched {1} Steps", 
         path.Id, path.Steps.Count); 
       } 
      } 

我基本上想說..

選擇(50)的路徑,也作爲一個單獨的選擇,但同一行程的一部分,選擇屬於先前第(12)步選定的路徑。

但是,如果我使用扁平連接,我得到110行,而我期望有2個表,50行中的1,600行中的1。

有人可以向我解釋我做錯了什麼嗎?請注意,我可以做一些小修改,查詢運行,但它不是'優化'的。我可以獲取我想要的數據,但需要多次旅行和延遲加載。我可以很容易地優化實際的Path選擇,但它是那些爆炸Step s。如果我只是從lpSteps查詢中取出限制性的where子句,它只會返回前12個步驟,而不是每完成一個查詢就返回12個步驟。

我看過Future<T>上的其他一些堆棧溢出帖子,發現它們看起來很像這個。所以我不明白爲什麼它不起作用。我懷疑發生了什麼事情是這樣的。

lpPaths運行。

lpSteps試圖運行,第一個成功。

lpSteps然後嘗試再次運行,發現它無法重新定義lpPaths。

Apocolypse

我真的希望有人比我聰明能見識一下絕對是最優化的方式來寫這個。

回答

0

我真的不明白你的用例是什麼。爲什麼你只需要每個路徑的前12步?怎麼樣批處理的步驟

IList<Guid> pathIds; 
while ((pathIds = QueryOver.For<Path>() 
    .Where(...) 
    .Projection(path => path.Id) 
    .SetmaxResults(100)).Count > 0) 
{ 

    int batch = 0; 
    const int batchsize = 600; 
    IList<Step> steps; 
    while ((steps = Session.QueryOver<Step>() 
     .Where(step => step.Path.Id).In(pathIds) 
     .Where(step => step. ...) 
     .SetFirstResult(batch * batchsize) 
     .Take(batchsize) 
     .List<Step>()).Count > 0) 
    { 
     DoSomething(steps); 
     batch++; 
    } 
} 
+0

12是一個任意數字,只是表示我需要能夠選擇一個有限的數字。 – Ciel

+0

那麼,這種方法確實只需要所需的行,但它並沒有在返回的實際模型中使它們前進,所以當迭代到「Path.Steps」時,它仍然會最終延遲加載它們... – Ciel

+0

那麼,我又回到了這裏,嘗試了更多的東西,讓我看看我是否明白你的建議。你說我應該爲我的'Path.Id'集合執行一個投影,然後'[B]'只是根據這些ID做查詢?這__does__以一種乾淨而有效的方式讓我得到所需的表,但是我怎麼去佈線以便不受訪問'Path.Steps'的延遲加載影響? – Ciel