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

StackOverflow https://stackoverflow.com/questions/660820

  •  20-08-2019
  •  | 
  •  

Вопрос

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

Система.Коллекции.Общее исключение.KeyNotFoundException:Данный ключ отсутствовал в словаре .

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

Это было полезно?

Решение 5

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

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

Другие советы

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

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

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

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

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

Вы создаете запрос к некоторому сопоставленному типу, а затем можете "спроецировать" этот запрос в "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 знал об этом.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top