Использование несопоставленного класса с именованным запросом NHibernate

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

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

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


person lomaxx    schedule 19.03.2009    source источник


Ответы (5)


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

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

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

person Michał Piaskowski    schedule 19.03.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 знал об этом.

person Frederik Gheysels    schedule 19.03.2009
comment
проекции - это не совсем то, что я ищу, но преобразователь TupleToPropertyResultTransformer или AliasToBean выполняет свою работу. У меня нет доступа к классу, чтобы дать ему новый конструктор для использования преобразователя AliasToBean, поэтому я использую TupleToPropertyResultTransformer - person lomaxx; 20.03.2009

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

person dnewcome    schedule 19.03.2009

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

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

person Stuart Childs    schedule 19.03.2009

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

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

person lomaxx    schedule 19.03.2009