开发者

NHibernate update using composite key

开发者 https://www.devze.com 2022-12-30 02:45 出处:网络
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:

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

精彩评论

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