Question

I have the following table

tblChild

FatherCode ChildNumber Name

FatherCode and ChildNumber are the primary keys of the table.

Since something like this happens very often in this database (I have ZERO control over it), I created the following class for me to map the Id:

public class ComposedId {
   public virtual int FatherId {get;set;}
   public virtual int ChildId {get;set;}
   //More code implementing Equals and GetHashCode
}

Now, the mapping goes like this:

aMapper.Class<Child>(aClassMapper => aClassMapper.ComposedId(aComposedIdMapper =>
                {
                    aComposedIdMapper.Property(aChild => aChild.Id); //Id's implementation is: public virtual ComposedId Id {get;set;}
                }));

aMapper.Class<Child>(aClassMapper => aClassMapper.ComponentAsId(aChild => aChild.Id, aComponentAsIdMapper =>
    {
        aComponentAsIdMapper.Property(aComposedId => aComposedId.FatherId, aPropertyMapper => aPropertyMapper.Column("FatherCode"));
        aComponentAsIdMapper.Property(aComposedId => aComposedId.ChildId, aPropertyMapper => aPropertyMapper.Column("ChildNumber"));
    }));

But when I'm try to query the table, NHibernate tries to get the Id as a column.

I don't know what I'm doing wrong, and I tried a lot of ways to map this with this structure, but nothing works :(

Was it helpful?

Solution

The first line in your mapping is incorrect.

I used this, which is just a simplified version of your code:

mapper.Class<Child>(cm => cm.ComponentAsId(
    x => x.Id,
    caim =>
    {
        caim.Property(x => x.FatherId, pm => pm.Column("FatherCode"));
        caim.Property(x => x.ChildId, pm => pm.Column("ChildNumber"));
    }));

And it correctly generated this mapping (XML-serialized):

<composite-id class="ComposedId" name="Id">
  <key-property name="FatherId" column="FatherCode" />
  <key-property name="ChildId" column="ChildNumber" />
</composite-id>

...which in turn produces correct SQL.

You say in the comments that you tried without the first line, but you probably forgot to compile, deploy or restart a server when testing it.

As a side note, if you rename the properties of ComposedId to match the db and use ConventionModelMapper, you don't even have to map the Id manually.


To get the XML mapping I use this:

var mappingDocument = mapper.CompileMappingForAllExplicitlyAddedEntities();
new XmlSerializer(typeof(HbmMapping)).Serialize(Console.Out, mappingDocument);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top