NHibernate.QueryException: дубликат пути ассоциации - PullRequest
4 голосов
/ 02 ноября 2011

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

Между зданиями и AttributeValues ​​существует отношение один ко многим, и моя цель - найти все здания, которые имеют AttributeValue из "Large" и AttributeValue из "Blue".

        var attributeValueAlias1 = new AttributeValue();
        var attributeValueAlias2 = new AttributeValue();

        var result = repository
            .CreateCriteriaFor<Buildings>()
            .Join(o=>o.AttributeValues, ()=> attributeValueAlias1)
            .Join(o=>o.AttributeValues, ()=> attributeValueAlias2)
            .Add(() => attributeValueAlias1.Value == "Large")
            .Add(() => attributeValueAlias2.Value == "Blue")
            .List();

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

Я могу сделать так, чтобы тест на членство был добавлен с помощью criteria.GetCriteriaByAlias(alias) перед добавлением псевдонима, чтобы ошибка «Дубликат псевдонима» не возникала, но при этом возникает только одно объединение, и это приводит к SQL-выражению where, которое никогда не будет истинным

SELECT *
FROM Buildings  this_
    inner join AttributeValues attributev1_
    on this_.Id = attributev1_.BuildingId
WHERE 
    attributev1_.Value = 'Large'
    and attributev1_.Value = 'Blue'

Это не сложный или необычный запрос, поэтому я бы удивился, если бы не было обходного пути.

1 Ответ

1 голос
/ 04 ноября 2011

Вы не должны использовать соединение, чтобы сделать это, как вы, вероятно, догадались из исключения.Вы должны использовать два подзапроса, чтобы проверить, находятся ли значения «Blue» и «Large» в коллекции.Я не очень хорош в ICriteria, но полученный SQL должен выглядеть следующим образом, и я думаю, что это возможно в ICriteria (с использованием Subqueries.PropertyIn).

select * from Buildings b
inner join AttributeValues av on b.Id = av.BuildingId
where av.Id in (select Id from AttributeValues av2 where av2.BuildingId=b.BuildingId and  av2.Value="Large")
and av.Id in (select Id from AttributeValues av3 where av3.BuildingId=b.BuildingId and av3.Value="Blue")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...