5

(私が思うに) シンプルであるべき何かに問題がありますが、明確な情報が見つかりません。

人が複数の仕事を持つことができるドメインを説明する 3 つのテーブルがあるシナリオでは、次のようになります。

Person - PersonId、Name
Job - JobId、JobName
を持つ PersonJob - PersonId、JobId、YearsOfEmployment を持つ

注: 私のオブジェクト モデルには、各テーブルを表すエンティティがあります。そこには有用なメタデータ (YearsOfEmployment) があり、単純な結合テーブルではないため、Person/Job 関係を表す 3 番目のエンティティがあります。

したがって、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 に答える