简体   繁体   中英

Nhibernate , collections and compositeid

I have the tables below:

Bucket(
 bucketId smallint (PK)
 name varchar(50)
)

BucketUser(
 UserId varchar(10) (PK) 
 bucketId smallint (PK)
)

The composite key is not the problem thats ok I know how to get around this but I want my bucket class to contanin a IList of BucketUser. I read the online reference and thought that I had cracked it but havent. The two mappings are below

-- bucket --

<class name="Bucket,Impact.Dice.Core" table="Bucket">
  <id name="BucketId" column="BucketId" type="Int16" unsaved-value="0">
    <generator class="native"/>
  </id>

  <property column="BucketName" type="String" name="BucketName"/>

  <bag name="Users" table="BucketUser" inverse="true" generic="true" lazy="true">
    <key>
      <column name="BucketId" sql-type="smallint"/>
      <column name="UserId" sql-type="varchar"/>
    </key>
    <one-to-many class="Bucket,Impact.Dice.Core" not-found="ignore"/>
  </bag>
</class>

-- bucketUser --

<class name="BucketUser,Impact.Dice.Core" table="BucketUser">
  <composite-id>
    <key-many-to-one name="BucketUser" class="Bucket,Impact.Dice.Core" column="BucketId"/>
    <key-property name="UserId" column="UserId" type="string"></key-property>
  </composite-id>
</class>

The key is the foreign key to the containing entity, not the primary key.

You have two options:

  • the class represents an independent entity, having an own id. It could be referenced from other classes, is always in the same table and could be loaded independently.
  • or it is a part of another entity with no independent identity. If referenced by other classes it is always in a separate table. It could not (easily) loaded independently from its parent entity.

Bucketuser is an idependent entity . It has its own mapping definition and you reference it using one-to-many. You get a composite key in your case, but I would avoid this.

<!-- reference to BucketUser. There is not table attribute needed. -->
<bag name="Users" inverse="true" generic="true" lazy="true">
  <key>
    <!-- foreign key -->
    <column name="BucketId" sql-type="smallint" />
  </key>
  <one-to-many class="Bucket,Impact.Dice.Core" not-found="ignore"/>
</bag>

<!-- BucketUser mapped as an independent entity -->
<class name="BucketUser" ... >
  <!-- here is the composite id, try to avoid this -->
  <composite-id>
    <key-property name="BucketId">
    <key-property name="UserId">
  </composite-id>
</bag>

Bucketuser is a dependent part of Bucket. The foreign key to the Bucket is the primary key at the same time:

<!-- The table is defined on the fly by the table attribute -->
<bag name="Users" table="BucketUser" inverse="true" generic="true" lazy="true">
  <key>
    <column name="BucketId" sql-type="smallint" />
  </key>
  <!-- use composite-element to define the contents of the table -->
  <composite-element>
    <!-- define the contents of the BucketUser here -->
    <property name="UserId" sql-type="varchar"/>
  </composite-element>
</bag>

It depends on your case which strategy is appropriate.

What error are you getting? If you really cut-and-pasted that mapping then the solution may be as simple as replacing the comma in

<one-to-many class="Bucket,Impact.Dice.Core" not-found="ignore"/>

with a period.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM