Использование Unmapped Class с именованным запросом NHibernate - PullRequest
3 голосов
/ 19 марта 2009

Я использую произвольный именованный запрос с NHibernate, который я хочу вернуть коллекцию объектов Person. Объект Person не сопоставлен с сопоставлением NHibernate, что означает, что я получаю следующее исключение:

System.Collections.Generic.KeyNotFoundException: Данный ключ отсутствовал в словарь.

Он генерируется, когда создается сеанс, потому что не может найти имя класса, когда вызывает NHibernate.Cfg.Mappings.GetClass (String className). Это все довольно понятно, но мне было интересно, есть ли способ сказать NHibernate использовать класс, даже если у меня нет сопоставления для него?

Ответы [ 5 ]

9 голосов
/ 19 марта 2009

Почему вы не используете:

query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));

Он будет вставлять данные из каждого столбца в вашем запросе в свойства объекта Person, используя псевдоним столбца в качестве имени свойства.

2 голосов
/ 19 марта 2009

Как создать запрос, который будет возвращать экземпляры типа, который не сопоставлен?

Я думаю, что у Михала есть смысл, и, возможно, вам стоит взглянуть на прогнозы. (По крайней мере, я думаю, это то, что вы ищете).

Вы создаете запрос для некоторого сопоставленного типа, а затем можете «проецировать» этот запрос на «DTO». Для этого вам нужно «импортировать» свой класс Person, чтобы он был известен NHibernate, и вам нужно будет использовать ResultTransformer.

Примерно так:

ICriteria crit = session.CreateCriteria (typeof(Person));

// set some filter criteria

crit.SetProjection (Projections.ProjectionList()
                     .Add (Property("Name"), "Name")
                     .Add (Property( ... )
                   );

crit.SetResultTransformer(Transformers.AliasToBean(typeof(PersonView));

return crit.List<PersonView>();

Но это все равно означает, что вам придется импортировать класс, чтобы NHibernate знал об этом.

0 голосов
/ 19 марта 2009

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

Тем не менее, вы не можете использовать именованный запрос для непосредственного внедрения результатов в не отображенный класс. Вам нужно будет указать, какие столбцы в какие поля поместить, или другими словами, отображение. ;) Однако вы можете вернуть скалярные значения из именованного запроса, а также взять эти объектные массивы и собрать свою коллекцию вручную.

0 голосов
/ 19 марта 2009

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

Кроме того, типы свойств выводятся, поэтому вам нужно быть осторожным с десятичными столбцами, возвращающими только целочисленные значения и т. Д. Кроме того, использование TupleToPropertyResultTransformer предоставило достаточно простой способ использования запроса SQL для возврата коллекции объектов без явного отображения объекты в NHibernate.

0 голосов
/ 19 марта 2009

Используя этот класс, NHibernate в основном будет угадывать все, что связано, включая таблицу, которую вы хотели использовать для Person, и сопоставления полей. NHibernate, вероятно, можно было бы взломать, чтобы выполнить динамическое связывание, основанное на сопоставлении имен или чего-то еще, но вся идея состоит в том, чтобы создать сопоставления из простого старого объекта данных с полями базы данных, используя файлы xml.

...