5

我遇到了一些(我认为)应该很简单但找不到任何明确信息的问题。

在我有三个表的场景中,描述一个人可以拥有多个工作的域:

Person - 有 PersonId,名称
Job - 有 JobId,JobName
PersonJob - 有 PersonId,JobId,YearsOfEmployment

注意:在我的对象模型中,我有代表每个表的实体。我有第三个实体来表示人员/工作关系,因为那里有有用的元数据(YearsOfEmployment),而不仅仅是一个简单的连接表。

那么,如果我知道 PersonId 和 JobId,是否有一种简单的方法可以让我使用会话并返回与这些 Id 匹配的对象?

或者,换一种方式,因为我已经知道主键是否存在脑死,简单的方法我可以将 SQL“SELECT YearsOfEmployment FROM PersonJob WHERE PersonId=1 AND JobId=1”变成类似的东西:

var keys = new {PersonId=1, JobId=2};
PersonJob obj = Session.Get<PersonJob>(keys);

顺便说一句:地图看起来像这样:

<class name="Person" table="dbo.Person" lazy="true">
  <id name="PersonId">
    <generator class="native"/>
  </id>
  <property name="Name"/>
</class>
<class name="Job" table="dbo.Job" lazy="true">
  <id name="JobId">
    <generator class="native"/>
  </id>
  <property name="JobName"/>
</class>
<class name="PersonJob" table="dbo.PersonJob" lazy="true">
  <composite-id>
    <key-property name="PersonId"></key-property>
    <key-property name="JobId"></key-property>
  </composite-id>
  <property name="YearsOfEmployment"/>
</class>
4

2 回答 2

8

好吧,我回答了我自己的问题。我认为发布您的问题几乎与与某人谈论它一样宣泄。如果我要让 PersonJob 的复合 ID 成为组件或类,即

<class name="PersonJob" table="dbo.PersonJob" lazy="true">
    <composite-id name="PersonJobKey" class="PersonJobKey">
      <key-property name="PersonId"></key-property>
      <key-property name="JobId"></key-property>
    </composite-id>
</class>

然后我可以简单地这样做:

PersonJobKey key = new PersonJobKey() { PersonId = 1, JobId = 1 };  
PersonJob obj = Session.Get<PersonJob>(key);  
int yearsOfEmployment = obj.YearsOfEmployment;

凉爽的。希望这可以帮助其他人弄清楚这一点...

于 2009-01-22T20:21:08.717 回答
3

感谢您在上面发布答案,我正在针对我已映射的复合键没有名称或类的对象查看它。当我尝试创建一个类来表示复合键时,它改变了对象在其他代码使用时的行为方式。我也想写一些类似的东西;

Session.Get<SalesRepArea>(new { AreaCode = "ACode", RegionCode = "RCode"});

我发现 nHibernate 无法理解匿名对象,但我确实意识到我不需要复合键的名称或类类型。实际上,nHibernate Get 方法所追求的是一个瞬态对象,以便它可以从数据库中获取它的等效对象(这就是为什么必须在 C# 类中重写 equals 方法才能使复合键工作的原因)。所以对于下面的地图

<class name="SalesRepArea">
   <composite-id>
      <key-property 
         name="AreaCode" column="AreaCode" type="String" length="12" />
      <key-property 
         name="RegionCode" column="RegionCode" type="String" length="12" />
   </composite-id>

我写的代码少了一点,并且省去了代表获取密钥的对象

SalesRepArea myArea = Session.Get<SalesRepArea>(
   new SalesRepArea()
   { 
      AreaCode = "ACode", 
      RegionCode = "RCode" 
   }
);

我并不是说命名键方法不好,代码越少并不总是越好,这只是表明 Hibernate 正在寻找键所在的对象以从数据库中获取特定对象。

如果我弄错了,请告诉我,但我希望这会有所帮助,因为我在这方面遇到了一些麻烦。

谢谢,

标记

于 2009-04-06T14:46:29.873 回答