В качестве примера, я удаляю незапрошенные и несущественные данные, чтобы выяснить, как выполнить первоначальный запрос.
У меня есть такая модель структуры.
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: элемент с тем же ключом уже добавлен.
Я не совсем уверен, как справиться с этим сценарием.если я использую Fetch
в запросе Path
, я получаю Select+N
ошибок от NHibernate Profiler.
У меня включено пакетирование, но, насколько мне известно, это действительно относится только к вставкам, а не к извлечению.Но в любом случае я получаю эти ошибки и не знаю, как с ними справиться.Любые идеи?
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 таблицы, 1 из 50 строк, 1 из 600 строк.
Может кто-нибудь объяснить мне, что я делаю не так?
Учтите, я могу внести незначительные изменения, и запрос будет выполнен, но он не "оптимизирован".Я могу получить нужные данные, но это требует многократных поездок и ленивой загрузки.Я могу достаточно легко оптимизировать фактический выбор Path
, но это те самые взорванные Step
с.Если я просто возьму ограничительное предложение where из запроса lpSteps
, он просто вернет первые 12 шагов, а не 12 шагов для каждого выполненного запроса.
Я просмотрел некоторые другие сообщения о переполнении стека на Future<T>
и обнаружил, что они выглядят примерно так.Поэтому я не понимаю, почему это не работает.Я подозреваю, что происходит следующее:
lpPaths работает.
lpSteps пытается запустить, первый успешный.
lpSteps затем пытается запустить снова, обнаруживает, что не может переопределить lpPaths.
Apocolypse
Яискренне надеясь, что кто-то умнее меня сможет просветить меня в том, что это самый оптимальный способ написать.