Выполнение левого внешнего соединения при применении фильтра nhibernate - PullRequest
1 голос
/ 01 сентября 2010

Я пытаюсь выполнить левое внешнее соединение с критериями nhibernate. У меня также есть фильтр, который применяется к моим запросам.

Проблема, с которой я столкнулся, заключается в том, что фильтр останавливает работу левого внешнего соединения, если результат соединения равен нулю.

В качестве очень простого примера я хочу вернуть всех музыкантов, и если они в группе, то и их группа

NHibernate генерирует следующий sql

SELECT this_.Name, band2_.Name
FROM   Musicians this_
       left outer join [Band] band2_
         on this_.BandID = band2_.ID
WHERE  (band2_.IsDeleted = 0)

, который не вернет музыкантов, если они не в группе. Я хочу что-то вроде

SELECT this_.Name, band2_.Name
FROM   Musicians this_
       left outer join [Band] band2_
         on this_.BandID = band2_.ID
WHERE  this_.ID = 4894 /* @p3 */
       (band2_.ID IS NULL OR band2_.IsDeleted = 0)

Возможно ли это с nhibernate?

UPDATE

var projections = new[]
                {
                    Projections.Property("Musician.Name").As("MusicianName"),
                    Projections.Property("Band.Name").As("BandName")
                };

            return this.sessionProvider.GetSession().CreateCriteria<Musician>("Musician")
                .CreateCriteria("Musician.Band", "Band", JoinType.LeftOuterJoin)
                .SetProjection(projections)
                .Add(Restrictions.Eq("Musician.ID", parameters.MusicianId))
                .SetResultTransformer(Transformers.AliasToBean<MusicianDetailsResult>())
                .UniqueResult<MusicianDetailsResult>();

Фильтр определяется с помощью FluentNHibernate

this.WithName(FilterName).WithCondition("IsDeleted = 0")

Ответы [ 2 ]

1 голос
/ 19 февраля 2015

Это ошибка в NHibernate .

Я использовал предложенный обходной путь и установил useManyToOne на фильтре в false. Это свойство в настоящее время отсутствует в FluentNhibernate, поэтому я просто делаю это в ExposeConfiguration

foreach (var key in cfg.FilterDefinitions.Keys)
{
  filter = cfg.FilterDefinitions[key];
  cfg.FilterDefinitions[key] = new  FilterDefinition(
    filter.FilterName,
    filter.DefaultFilterCondition, 
    filter.ParameterTypes, false);
}
0 голосов
/ 01 сентября 2010

Во-первых, это намного проще, если вы просто сопоставите Band с Musician в качестве ссылки:

public class MusicianDbMap : ClassMap<Musician>
{
    public MusicianDbMap()
    {
         ...
         References(x => x.Band)
             .Nullable()
             .Not.LazyLoad(); // Or lazy load... either way
    }
}

Тогда вы можете просто выполнить простой запрос - вот он в Linq-2-NHibernate:

 Session.Linq<Musician>()
      .Where(x => x.Band == null || !x.Band.IsDeleted)
      .ToList();

Во-вторых, я не уверен насчет вашего заявления: «которое не вернет музыкантов, если они не в группе» ... Я не уверен, что это правильно.Левое внешнее соединение должно возвращать все строки, независимо от того, находятся они в группе или нет - вы уверены, что не допустили ошибку где-то еще?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...