开发者

NHibernate update using composite key

I have a table defnition as given below:

License

ClientId
Type
Total
Used

ClientId and Type together uniquely identifies a row. I have a mapping file as given below:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
  <class name="Acumen.AAM.Domain.Model.License, Acumen.AAM.Domain" lazy="false" table="License">
<id name="ClientId" access="field" column="ClientID" />
<property name="Total" access="field" column="Total"/>
<property name="Used" access="field" column="Used"/>
<property name="Type" access="field" column="Type"/>
  </class>
</hibernate-mapping>

If a client used a license to create a user, I need to update the Used column in the table. As I set ClientId column as t开发者_C百科he id column for this table in the mapping xml, I am getting TooManyRowsAffectedException.

could you please let me know how to set a composite key at mapping level so that NHibernate can udpate based on ClientId and Type.

Something like: Update License SET Used=Used-1 WHERE ClientId='xxx' AND Type=1

Please help.

Thanks, Mahesh


You have to use a composite-id

http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-compositeid


If you primary key is composite, your mapping should reflect that, and your class needs to override Equals and GetHashCode.

Also, if ClientId is the primary key of your Client entity, you should map it as many-to-many, not just an Id.

Also, why are you specifying lazy="false"? Are you aware of the implications?

Also, why map everything with access="field"? Do the properties have some special logic?

This is a revised mapping considering everything I just wrote. Feel free to ignore those parts that don't apply :-)

<class name="Acumen.AAM.Domain.Model.License, Acumen.AAM.Domain" table="License">
  <composite-id>
    <key-many-to-one name="Client" column="ClientID" />
    <key-property name="Type" />
  </composite-id>
  <property name="Total" />
  <property name="Used" />
</class>


As the other comrades mentioned above, you have to use a composite-id, which is not a best but acceptable practice.

On the other hand, you can simply write an update interceptor and make sure your Type = 1 within it.

Here are some link about the topic to help you see clear in this.

  1. Elegant code : Implementing NHibernate Interceptors
  2. NHibernate Documentation : Interceptors
  3. Sample NHibernate IInterceptor implementation
  4. Enterprise .NET Community : NHibernate Part 2 (Scroll down to : Interceptors and Persistent Lifecycle)
  5. NHibernate Interceptor Auditing Inserted Object Id (SO question)

The main advantage of using interceptors over a composite key is that it doesn't break your DBRM and provides a definitely more flexible solution, without "polluting" your mapping file which will more precisely represent your model.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜