我对NHibernate相当新,我需要提出一些与常见情况有关的问题。以下简化示例说明了该问题。
我有两个名为Equipment和Users的表。用户是一组系统管理员。设备是一套机器。
表:
行为:
在Equipment.UpdatedBy上没有外键约束,这意味着:
要查找设备和上次更新设备的人,我可能会这样查询:
选择E.EquipId,E.EquipName,U.UserId,U.LoginName 来自Equipment 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是从设备中选择全部,后面是UserId = n 的用户中的许多选择列,而我期望NHibernate按照普通的普通SQL左键加入,然后点击一下。如果我能告诉NHibernate一次性执行查询,我该怎么做?
时间对我的项目至关重要,因此感谢您提供的任何帮助。如果你在猜测NHibernate在这种情况下如何工作,请说你不是很确定。非常感谢。
答案 0 :(得分:0)
在你的映射中,添加not-null = false,如下所示:
<many-to-one name="UpdatedBy" class="User" column="UpdatedBy" not-null="false" />
在您的代码中,请勿检查用户是否设置了国家/地区,以确定是否有人更新了该国家/地区。如果User为null,则会导致NullPointerException。而是检查User是否为null:
User user = item.UpdatedBy;
if (user != null)
Debug.WriteLine("Updated By: " + user.LoginName);
else
Debug.WriteLine("Updated by: Nobody");