NHibernate QueryOver Выбрать только необходимую модель - PullRequest
1 голос
/ 03 апреля 2011

Я столкнулся с небольшой проблемой при выборе только необходимой модели в QueryOver. Вот мой сценарий

 var qOver = _HibSession.QueryOver<ModelA>(() => Ma)
                .JoinAlias(() => Ma.MbList, () => Mb, JoinType.LeftOuterJoin)
                    .Where(() => Mb.ID == _MbId)
                .JoinAlias(() => Mb.McList, () => Mc,JoinType.LeftOuterJoin)                    
                    .Where(() => Mc.ID == _McId)
                .JoinAlias(() => Mc.MdList, () => Md, JoinType.LeftOuterJoin)
                    .Where(() => Md.ID == _MdID)                                             
                .OrderByAlias(() => Ma.ID).Asc
                .Take(iTake)
                .Skip(iSkip)
                .Future<ModelA>();

Предыдущий код генерирует следующий SQL

SELECT TOP n Ma.*,Mb.*,Mc.*,Md.*
FROM Ma 
LEFT JOIN Mb ON (...conditions...)
LEFT JOIN Mc ON (...conditions...)
LEFT JOIN Md ON (...conditions...)
WHERE Mb.ID = _MbId
AND Mc.ID = _McId
AND Md.ID = _MdId
ORDER BY Ma.ID ASC

Проблема в том, что таблица Mc и Md дублирует мой результат. Таким образом, в моем операторе SELECT будут только Ma и Mb.

SELECT TOP n Ma.*,Mb.*
FROM
.
.
.

Как мне достичь этого результата? Спасибо!

Ответы [ 3 ]

2 голосов
/ 03 апреля 2011

Вы должны сообщить NHibernate, чтобы не повторять корневую сущность (ModelA).Вы можете сделать это с заявлением:

.TransformUsing(Transformers.DistinctRootEntity)
2 голосов
/ 03 апреля 2011

Попробуйте использовать Fetch вместо JoinAlias.Примерно так должно работать:

... .QueryOver<Ma>().Fetch(ma => ma.MbList).Eager

и делать не использовать fetch="join" в вашем отображении.

Когда вы заставляете NHibernate использовать joinон вернет столько строк, сколько есть в декартовом произведении ваших таблиц.Поскольку вам нужен только один элемент списка на объект ModelA, вы должны позволить NHibernate использовать простые операторы select вместо join.

0 голосов
/ 30 мая 2011

Похоже, единственный способ - использовать ценовой QueryOver, выбирая основную модель и отфильтрованный подзапрос

Я имею в виду что-то вроде этого

var qOverInclude = QueryOver.Of<MyModel>(() => mModel)
                .JoinAlias(() => mModel.MyList, () => mList, JoinType.LeftOuterJoin)
                    .Where(() => mList.ID == myID)
                    .And(() => mList.Type == myType)
                .Select(x => x.IdMyModel);

  var qOver = _HibSession.QueryOver<MyModel>(() => mModel)
                .JoinAlias(() => mModel.MyDescription, () => mDescription, JoinType.LeftOuterJoin)
                .Where(() => mDescription.IDLanguage == myLanguage)
                .WithSubquery.WhereProperty(() => mModel.IdMyModel).In(qOverSubQuery)
                .OrderByAlias(() => mModel.IdMyModel).Asc
                .Future<MyModel>();
...