How to map composite-id with fluent nhibernate usi

2019-02-24 10:42发布

问题:

I'm trying to switch out .hbm mappings to fluent mappings and have a problem with the mapping of composite-ids and the usage of Interfaces

the Class looks as follows:

public class ClassWithCompositeId {
  public virtual IKeyOne KeyOne { get; set; }
  public virtual IKeyTwo KeyTwo { get; set; }
}

our hbm mapping looks like this:

<hibernate-mapping ...>
   <class name="ClassWithCompositeId" table="t_classwithcompositeid">
      <composite-id>      
         <key-many-to-one name="KeyOne" column="colkeyone" class="company.namespace.boSkillBase, BL_Stammdaten" />
         <key-many-to-one name="KeyTwo" column="colkeytwo" class="boQualifikation" />         
      </composite-id>
</hibernate-mapping>

Please note, that we got interfaces in the Class! No I'm trying to map this with Fluent nhibernate.

Map {
   public ClassWithCompositeIdMap() {
         CompositeId()
            .KeyReference(x => x.KeyOne, "colkeyone")
            .KeyReference(x => x.KeyTwo, "colkeytwo");
          ...
   }
}

But now Fluent generates the Mapping as follows:

...
 <composite-id mapped="false" unsaved-value="undefined">
      <key-many-to-one name="KeyOne" class="company.namespace.IKeyOne, Interfaces, Version=0.1.4.3379, Culture=neutral, PublicKeyToken=null">
        <column name="colkeyone" />
      </key-many-to-one>
      <key-many-to-one name="KeyTwo" class="company.namespace.IKeyTwo, Interfaces, Version=0.1.4.3379, Culture=neutral, PublicKeyToken=null">
        <column name="colkeytwo" />
      </key-many-to-one>
    </composite-id>
...

The "Class" Attribute points now to the Interface not to the implementation of this interface which results in an error.

How can I tell Fluent nHibernate to use another class as the attribute value?

回答1:

Try downloading NhGen from SourceForge. It reads database schemas and generates Fluent mappings and classes etc. While all the code might not be what you need, it should start you off in the right direction as it supports composite keys and represents them as separate classes off the main entity.

I beleive it uses a syntax similar to

 CompositeId()
            .ComponentCompositeIdentifier(x => x.Key, "Namespace.Key, Assembly")
            .KeyProperty(x => x.Key.Id1, "Id1")
            .KeyProperty(x => x.Key.Id2, "Id2")
            .KeyProperty(x => x.Key.Id3, "Id3");


回答2:

Tanks! But I've found the answer on my on. In fact i found a missing feature in fluent nHibernate. The feature has already been added to the dev branch by Paul Batum.

You would use it like so:

   Map {
      public ClassWithCompositeIdMap() {
            CompositeId()
               .KeyReference(x => x.KeyOne, k =>
                   k.Type<KeyOneImplementation>(), "colkeyone")
               .KeyReference(x => x.KeyTwo, k =>
                   k.Type<KeyTwoImplementation>(), "colkeytwo");
             ...
      }
   }

http://github.com/paulbatum/fluent-nhibernate/tree/dev

You can see the original Conversation here: http://support.fluentnhibernate.org/discussions/help/349-how-to-map-a-composite-id-when-using-interfaces-or-how-to-change-the-class-attribute-in-the-key-many-to-one-tag