爲了舉例,我刪除了非查詢和非必要的數據,只是爲了弄清楚如何在這裏執行初始查詢。與特定的未來<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
我真的希望有人比我聰明能見識一下絕對是最優化的方式來寫這個。
12是一個任意數字,只是表示我需要能夠選擇一個有限的數字。 – Ciel
那麼,這種方法確實只需要所需的行,但它並沒有在返回的實際模型中使它們前進,所以當迭代到「Path.Steps」時,它仍然會最終延遲加載它們... – Ciel
那麼,我又回到了這裏,嘗試了更多的東西,讓我看看我是否明白你的建議。你說我應該爲我的'Path.Id'集合執行一個投影,然後'[B]'只是根據這些ID做查詢?這__does__以一種乾淨而有效的方式讓我得到所需的表,但是我怎麼去佈線以便不受訪問'Path.Steps'的延遲加載影響? – Ciel