CreateQuery и CreateCriteria, генерирующие разные SQL-запросы - PullRequest
0 голосов
/ 13 января 2010

Клиент имеет свойства Report, Configuration и т. Д. Клиент может иметь только один из каждого. Также каждый отчет может принадлежать только одному Клиенту. Это в некотором роде отношения один к одному. Поэтому в моей таблице отчетов есть столбец внешнего ключа clientID. То же самое для конфигурации и других таблиц.

Теперь, согласно определению «один к одному», которое я прочитал на сайте nhibernate, это означает, что и первичные ключи Report и Client должны быть одинаковыми. Допустим, я не могу реализовать это таким образом. Следовательно, чтобы смоделировать структуру, которую я имею в базе данных, у меня есть следующие отображения:

ReportMap

References(x => x.Client, "clientID").Unique().Not.Nullable();

ClientMap

HasOne(x => x.Report).PropertyRef(x => x.Client).LazyLoad().Cascade.SaveUpdate();

Теперь проблема, с которой я сталкиваюсь, заключается в том, что когда я запрашиваю клиента, NHibernate также генерирует запросы для получения отчета, конфигурации и т. Д. Кроме того, в зависимости от того, использую ли я Criteria или HQL, сгенерированные запросы сильно отличаются.

var client = session.CreateQuery("from Client as c where c.Id = :clientId")
                    .SetParameter("clientId", 1L)
                    .UniqueResult<Client>();

создает один запрос для клиента, за которым следует один запрос для каждого свойства, которое я сопоставил как HasOne. т.е. еще 2 запроса. Один для отчета и один для конфигурации. HQL генерирует всего 3 запроса.

Однако, если я использую метод Load или Критерии , он генерирует один запрос, который объединяет все соответствующие таблицы .

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

Какое логическое объяснение этому?

Из документации Nhibernate о стратегиях извлечения я понимаю, что одиночные ассоциации извлекаются ленивым прокси. и что стратегия выборки по умолчанию выбора выполняется только при обращении к ассоциации. В моем случае я не имею доступа к ассоциации. Я просто читаю свойства, которые принадлежат Клиенту.

Все это так запутанно ...

Edit1 : Я сопоставил свое отношение один к одному, как упомянуто в документации по nhibernate. http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone

Есть две разновидности один-к-одному ассоциации:

* primary key associations
* unique foreign key associations

В качестве альтернативы внешний ключ с уникальным ограничением, от Сотрудника до Человека, может быть> выражен как:

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>

И эта связь может быть сделана двунаправленной, добавив следующее в Person> mapping:

<one-to-one name="Employee" class="Employee" property-ref="Person"/>

Технически, насколько я понимаю, я не делаю ничего плохого. Предполагается, что этот сценарий поддерживается nhibernate.

1 Ответ

1 голос
/ 13 января 2010

Я не уверен, в чем проблема с вашим запросом, но я предлагаю вам изменить отображение. У вас есть отношение один-ко-многим между Client-Report и бизнес-правилом, согласно которому у клиента может быть только один отчет. Вы должны отобразить это как таковой. Коллекция отчетов может быть отображена как закрытый член, и вы можете предоставить свойство Report в Client для применения бизнес-правила. Я ожидаю, что отображение этого пути решит проблему вашего запроса.

Вы также можете сопоставить его в другом направлении с Клиентом на другой стороне, если это имеет больше смысла.

...