Возникли проблемы с конкретными запросами Future <T>и коллекциями с помощью nHibernate. - PullRequest
0 голосов
/ 30 июля 2011

В качестве примера, я удаляю незапрошенные и несущественные данные, чтобы выяснить, как выполнить первоначальный запрос.

У меня есть такая модель структуры.

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

Яискренне надеясь, что кто-то умнее меня сможет просветить меня в том, что это самый оптимальный способ написать.

1 Ответ

0 голосов
/ 31 июля 2011

Я не могу понять, каков ваш вариант использования.зачем вам нужны только первые 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++;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...