Подтвердить что ты не робот

Задание стратегии выборки (select, join и т.д.) в запросе запроса nhibernate

Я пытаюсь создать запрос с помощью QueryOver, который будет извлекать коллекцию в режиме Select или SubSelect. Сущность, о которой идет речь, составляет Track. Я хочу загрузить коллекцию с именем TrackPrices, и я делаю это в запросе:

q = q.Fetch(item => item.TrackPrices).Eager;

Однако это создает левое соединение, что приводит к проблеме для разбивки на страницы. Я бы хотел, чтобы он выполнял отдельный выбор или подзапрос. Любая идея, если это можно сделать? Насколько я знаю, используя API критериев, вы бы сделали:

q.DetachedCriteria.SetFetchMode("TrackPrices", FetchMode.Select);

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

4b9b3361

Ответ 1

С момента, когда я разместил этот вопрос, мне удалось найти обходное решение/решение, которое другие могут найти полезным.

В принципе, в этом случае вы должны сначала создать другой запрос, который четко выбирает первичные ключи основного запроса вместе с разбиением на страницы. Поскольку DISTINCT (ID) вернет только те результаты, которые вы хотите, вы можете использовать разбиение на страницы SQL без каких-либо проблем. Затем вы повторно запускаете основной запрос без разбивки на страницы, но используете условие, в котором идентификатор находится в одном из возвращаемых списков. Я создал общий метод, который принимает критерии, просматривает возвращаемые идентификаторы и добавляет их как условие к основным критериям. Код ниже:

public static void LimitCriteriaByPrimaryKeys(this NHibernate.ICriteria criteria, string primaryKeyName, int pageNum, int pageSize)
    {
        var session = NHManager.Instance.GetCurrentSessionFromContext();
        if (pageSize <= 0) pageSize = Int32.MaxValue - 1;
        var nhSession = NHManager.Instance.GetCurrentSessionFromContext();
        var pagingCriteria = (ICriteria)criteria.Clone();
        IList ids = null;
        var pKeyIDName = Projections.Property(primaryKeyName);  
        var pKeyProjection = Projections.Distinct(pKeyIDName); 
        {
            {
                //paging
                pagingCriteria.SetProjection(pKeyProjection); //sets the primary key distinct projection
                if (pageSize > 0)
                {

                    if (pageNum < 1)
                        pageNum = 1;
                    int skipAmt = (pageNum - 1) * pageSize;
                    pagingCriteria.SetFirstResult(skipAmt);
                    pagingCriteria.SetMaxResults(pageSize); 

                    ids = pagingCriteria.List(); //this returns the distinct list of IDs which should be returned for the given page & size

                }
            }
        }
        {
            if (ids != null && ids.Count > 0)
            {
                criteria.Add(Expression.In(pKeyIDName, ids));   //adds the primary key restriction
                var crit = criteria;
                crit.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());
            }
            else
            {
                criteria.Add(Expression.Eq(pKeyIDName, 0)); //this is added specifically so that the main criteria returns NO results
                criteria.Add(Expression.Eq(pKeyIDName, 1));
            }
        }
    }

Методы NHManager.Instance.GetCurrentSessionFromContext(); могут быть заменены вашим собственным методом для извлечения текущего сеанса из сеанса factory.

Надеюсь, что это поможет!

Ответ 2

Я знаю, что это не то, о чем вы просили, но в худшем случае вы можете инкапсулировать свои магические строки безопасным типом с использованием различных методологий здесь: С# String enums

Ответ 3

Сочетание пейджинга и нетерпеливой выборки сложно.

Если вы укажете выборку для выбора через API критериев, каждый элемент в TrackPrices будет загружен в отдельный запрос - N + 1. Вам не нужно беспокоиться о полной загрузке.

Вы можете установить размер партии для TrackPrices при сопоставлении для устранения проблемы N + 1. В этой статье есть несколько деталей о том, как смешивать нетерпеливые выборки и подкачки.