Как этот код NHibernate влияет на коммит? - PullRequest
0 голосов
/ 31 января 2020

Я столкнулся с проблемой, когда следующий код приводит к исключению.

public IList<Persoon> GetPersonenWithCurrentWorkScheme(int clientId)
    {
        //SELECT N+1
        Session.QueryOver<Werkschema>()
            .Fetch(ws => ws.Labels).Eager
            .JoinQueryOver<WerkschemaHistory>(p => p.Histories)
            .JoinQueryOver<ArbeidsContract>(a => a.ArbeidsContract)
            .JoinQueryOver<Persoon>(p => p.Persoon)
            .Where(p => p.Klant.ID == clientId)
            .Future();

        var result = Session.QueryOver<Persoon>()
            .Fetch(p => p.ArbeidsContracten).Eager
            .Where(p => p.Klant.ID == clientId)
            .Future();

        return result.ToList();
    }

Когда я комментирую первую часть метода (Session.QueryOver WerkSchema...), код работает нормально. Когда это не комментируется, первое NHibernate.Commit(), которое происходит, вызывает исключение. (Что-то с преобразованием даты и времени, но это не совсем то, о чем я беспокоюсь).

Мой вопрос: полезен ли первый кусочек кода? Это что-нибудь делает? Результат не сохраняется в переменной, которая используется позже, поэтому для меня это выглядит как мертвый код. Или это некая темная магия NHibernate c, которая действительно делает что-то полезное?

1 Ответ

1 голос
/ 31 января 2020

Future - это оптимизация по сравнению с существующим API, предоставляемым NHibernate.

Одна из самых приятных новых функций в NHibernate 2.1 - это Future () и FutureValue () функции. По сути, они функционируют как способ отложить выполнение запроса на более позднюю дату, после чего NHibernate получит больше информации о том, что должно делать приложение, и соответственно оптимизирует его. Это основано на существующей функции NHibernate, Multi Queries, но делает это простым в использовании и практически бесшовным способом.

Это выполнит несколько запросов за один прием в базу данных. Если невозможно получить все необходимые данные в одном цикле, несколько вызовов будут выполнены, как и ожидалось; но это все еще помогает во многих случаях.

Вызов базы данных запускается при запросе первого запроса туда и обратно.

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

Как вы подозреваете, вывод первой части; хотя извлеченный никогда не используется. Так что, на мой взгляд, эту часть можно смело комментировать. Но это основано на коде, который вы публикуете только в вопросе.

Может случиться так, что данные, загруженные во время этого вызова, сохраняют циклические переходы в другой части кода. Но в этом случае код должен быть оптимизирован и перемещен в нужное место.

...