#nhibernate
#nhibernate
Вопрос:
У меня такая проблема.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Altkom.Model" namespace="Altkom.Model">
<class name ="Employee" table="Employee" discriminator-value="Employee">
<id name ="EmployeeId" column="EmployeeId">
<generator class="uuid.hex" />
</id>
<discriminator column="Discriminator" not-null="true" type="System.String"/>
<property name="FirstName" column="FirstName" not-null="true" />
<property name="LastName" column="LastName" not-null="true" />
<property name="BirthDate" column="BirthDate" not-null="true"/>
<property name="Sex" column="Sex" not-null="true" />
<!--<property name="ManagerId" column="ManagerId"/>-->
<component name="Address" class="Altkom.Model.Address, Altkom.Model">
<property name="City" column="City" not-null="true" />
<property name="Street" column="Street" not-null="true" />
<property name="Country" column="Country" not-null="true" />
<property name="ZipCode" column="ZipCode" not-null="true" />
</component>
<bag name="Projects" table="EmployeeProject" lazy="true">
<key column="EmployeeId"/>
<many-to-many column="ProjectId" class="Project" />
</bag>
<bag name="JobHistories" lazy="false">
<key column="EmployeeId"/>
<one-to-many class="JobHistory"/>
</bag>
<many-to-one name ="Manager" class="Altkom.Model.Manager, Altkom.Model" column="ManagerId"/>
<subclass name="Manager" discriminator-value="Manager">
<!--<many-to-one name ="Employee" class="Altkom.Model.Employee, Altkom.Model" column="EmployeeId" not-null="false" cascade="all-delete-orphan" lazy="false"/>-->
<bag name="Subordinates" lazy="false" inverse="true" cascade="all-delete-orphan">
<key column="ManagerId"/>
<one-to-many class="Employee"/>
</bag>
<property name="RoomNumber" column="RoomNumber"/>
</subclass>
</class>
</hibernate-mapping>
Структура таблицы является:
CREATE TABLE [dbo].[Employee](
[EmployeeId] [nvarchar](255) NOT NULL,
[Discriminator] [nvarchar](255) NOT NULL,
[FirstName] [nvarchar](255) NOT NULL,
[LastName] [nvarchar](255) NOT NULL,
[BirthDate] [datetime] NOT NULL,
[Sex] [int] NOT NULL,
[City] [nvarchar](255) NOT NULL,
[Street] [nvarchar](255) NOT NULL,
[Country] [nvarchar](255) NOT NULL,
[ZipCode] [nvarchar](255) NOT NULL,
[ManagerId] [nvarchar](255) NULL,
[RoomNumber] [nvarchar](255) NULL,
PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [FK74988DB23FED7E5D] FOREIGN KEY([ManagerId])
REFERENCES [dbo].[Employee] ([EmployeeId])
GO
ALTER TABLE [dbo].[Employee] CHECK CONSTRAINT [FK74988DB23FED7E5D]
GO
Что я должен сделать, чтобы свойство Subordinates работало хорошо.
Спасибо за любой совет.
Комментарии:
1. Безусловно, возможно создать коллекцию объектов, которые поступают из набора данных с самоссылками, используя NHibernate. Но прямо сейчас мы даже не знаем, есть ли у вас какие-либо проблемы. Потребовалось бы больше усилий, чем большинству людей приходится тратить на эти вопросы, чтобы на самом деле заставить ваш код попытаться выполнить. Нет смысла даже утруждать себя просмотром чужого файла сопоставления, даже не зная, в чем проблема. Вам нужно описать любые ошибки, которые вы получаете, или поведение, которое не соответствует вашим потребностям, и кто-нибудь, вероятно, сможет ответить.
2. Здравствуйте, спасибо за ваш ответ. Моя проблема с коллекцией подчиненных. Это свойство всегда пустое, даже если у меня есть записи в базе данных, которые соответствуют критериям. Я не получаю никакой ошибки. Все выглядит хорошо, но только одно это свойство ведет себя не так, как я хочу.
3. Еще раз привет, все работает хорошо. Моя ошибка, я должен идти спать 🙂
4. ОК. Я думаю, что в будущем вы можете счесть эту модель чрезмерно ограничительной и проблематичной. Моделирование «ролей» по наследованию приводит к проблемам. В вашей модели, если кто-то является «Менеджером», это фундаментальная часть его идентификации сущности. Если у нас есть базовый класс «Млекопитающее», у нас могли бы быть подклассы «Кошка», «Собака», «Человек», и все они были бы частью истинной фундаментальной сущности identity. «Менеджер» не соответствует этой парадигме, это роль, переходная, а не идентичность. Я советую использовать один класс (Person или Employee и т.д.) С коллекцией объектов роли. Ролью может быть «Менеджер» и т.д.
Ответ №1:
Мы используем довольно похожую структуру в приложении NH. Различия, которые я вижу в вашем отображении, заключаются в следующем:
1) Мы не вкладываем определения классов 2) Мы указываем fetch=’select’ для элемента «многие к одному» 3) Мы используем lazy=’true’ для элемента bag
Таким образом, переработка вашего сопоставления будет выглядеть следующим образом:
<class name ="Employee" table="Employee" discriminator-value="Employee">
...
<many-to-one name ="Manager" fetch="select" class="Altkom.Model.Manager, Altkom.Model" column="ManagerId"/>
...
</class>
<subclass name="Manager" extends="Employee" discriminator-value="Manager">
<bag name="Subordinates" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="ManagerId"/>
<one-to-many class="Employee"/>
</bag>
...
</subclass>
[В качестве отступления я задаюсь вопросом, действительно ли вы хотите использовать подкласс для Manager. Что происходит, когда кто-то получает повышение? Или вы просто хотите назначить младшего подчиненного? Вам нужно будет изменить тип этого объекта и, возможно, воссоздать строку и обновить все связанные записи. Обычно я использую только другой класс, где существует достаточно строгая неизменяемость типа]