Я довольно новичок в NHibernate, и мне нужно задать пару вопросов, касающихся очень частого сценария. Следующий упрощенный пример иллюстрирует проблему.
У меня есть две таблицы с именами Оборудование и Пользователи. Пользователи - это набор системных администраторов. Оборудование представляет собой набор машин.
Таблица:
- Таблица пользователей имеет UserId int и LoginName nvarchar (64).
- Таблица оборудования имеет EquipId int, EquipType nvarchar (64), ОбновленоBy int.
Поведение:
- Системные администраторы могут вносить изменения в оборудование, и когда они это делают, поле «Обновленное оборудование» «обычно» устанавливается на свой идентификатор пользователя.
- Пользователи могут быть удалены в любое время.
- Новые предметы экипировки имеют значение Updates, равное нулю.
На Equipment.UpdatedBy нет ограничений по внешнему ключу, что означает:
- Equipment.UpdatedBy может быть нулевым.
- Значение Equipment.UpdatedBy может быть = существующее значение User.UserId
- Значение Equipment.UpdatedBy может быть = несуществующее значение User.UserId
Чтобы найти снаряжение и кто последний раз обновлял снаряжение, я мог бы запросить вот так:
выберите E.EquipId, E.EquipName, U.UserId, U.LoginName
из оборудования E
левое внешнее объединение Пользователи U вкл. E.UpdatedBy = U.UserId
Достаточно просто.
Так как это сделать в NHibernate?
Мои отображения могут быть следующими:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Data"
assembly="Data">
<class name="User" table="Users">
<id name="Id" column="UserId" unsaved-value="0">
<generator class="native" />
</id>
<property name="LoginName" unique="true" not-null="true" />
</class>
<class name="Equipment" table="Equipment">
<id name="Id" column="EquipId" type="int" unsaved-value="0">
<generator class="native" />
</id>
<property name="EquipType" />
<many-to-one name="UpdatedBy" class="User" column="UpdatedBy" />
</class>
</hibernate-mapping>
Так как мне получить все предметы экипировки и кто их обновил?
using (ISession session = sessionManager.OpenSession())
{
List<Data.Equipment> equipList =
session
.CreateCriteria<Data.Equipment>()
// Do I need to SetFetchmode or specify that I
// want to join onto User here? If so how?
.List<Data.Equipment>();
foreach (Data.Equipment item in equipList)
{
Debug.WriteLine("\nEquip Id: " + item.Id);
Debug.WriteLine("Equip Type: " + item.EquipType);
if (item.UpdatedBy != null)
Debug.WriteLine("Updated By: " + item.UpdatedBy.LoginName);
else
Debug.WriteLine("Updated by: Nobody");
}
}
Когда Equipment.UpdatedBy = 3, а Users.UserId = 3 отсутствует, вышеприведенный сбой
У меня также есть ощущение, что сгенерированный SQL - это выбор всего из Оборудования , за которым следуют многие выбор столбцов в Users, где UserId = n , тогда как я ожидал, что NHibernate оставит соединение согласно моему простому обычному SQL и сделать один удар. Если я скажу NHibernate сделать запрос одним нажатием, как мне это сделать?
Время имеет большое значение для моего проекта, поэтому любая помощь, которую вы можете оказать, с благодарностью получена. Если вы размышляете о том, как NHibernate может работать в этом сценарии, скажите, что вы не совсем уверены. Большое спасибо.