NHibernate映射和查询表相关但没有外键约束的位置

NHibernate映射和查询表相关但没有外键约束的位置,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我对NHibernate还比较陌生,我需要问几个关于一个非常常见的场景的问题。下面的简化示例说明了该问题 我有两个名为设备和用户的表。用户是一组系统管理员。设备是一套机械 表: Users表具有UserId int和LoginName nvarchar64。 设备表具有EquipId int,EquipType nvarchar64,由int更新。 行为: 系统管理员可以对设备进行更改,当他们进行更改时,设备的UpdatedBy字段通常设置为其用户Id。 用户可以随时删除。 新设备项的Updat

我对NHibernate还比较陌生,我需要问几个关于一个非常常见的场景的问题。下面的简化示例说明了该问题

我有两个名为设备和用户的表。用户是一组系统管理员。设备是一套机械

表:

Users表具有UserId int和LoginName nvarchar64。 设备表具有EquipId int,EquipType nvarchar64,由int更新。 行为:

系统管理员可以对设备进行更改,当他们进行更改时,设备的UpdatedBy字段通常设置为其用户Id。 用户可以随时删除。 新设备项的UpdatedBy值为null。 设备上没有外键约束。更新通过以下方式:

Equipment.UpdatedBy可以为空。 Equipment.UpdatedBy值可以是=现有的User.UserId值 Equipment.UpdatedBy值可以是=不存在的User.UserId值 要查找设备以及上次更新设备的人,我可以这样查询:

<many-to-one name="UpdatedBy" class="User" column="UpdatedBy" not-null="false" />
选择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是从设备中全选,然后是从UserId=n的用户中选择的许多列,而我希望NHibernate按照我的普通SQL左键连接并执行一次命中。如果我能告诉NHibernate一次完成查询,我该怎么做


时间对我的项目至关重要,所以我们非常感谢您提供的任何帮助。如果您正在猜测NHibernate在这种情况下如何工作,请说您不是绝对确定。非常感谢。

在映射中,添加not null=false,如下所示:

<many-to-one name="UpdatedBy" class="User" column="UpdatedBy" not-null="false" />

谢谢有没有可能让NHibernate在一次点击中获得所有数据?您可以设置一个标准来获取连接到设备的所有用户。或者获取所有连接有用户的设备,并像以前一样遍历这些设备。您是否有类似criteria api查询的粗略示例。我发现标准api是hibernate中最难掌握的部分。我经常查看现有的sql查询,并思考如何使用CriteriaAPI来表达所有这些。