HasMany() in mapping generates an unexpected column name in child table.

shiften's Avatar

shiften

21 Mar, 2010 04:02 AM via web

I have two classes, one NormalizationPathMeasurement has the following mapping:

        this.HasMany(x => x.DataPoints)
            .Inverse()
            .Cascade.All().AsBag();

DataPoints is a List<NormalizationData>, which has the following mapping:

        this.References(x => x.PathMeasurement)
            .Not.Nullable()
            .Index("idx_NormalizationData_References");

However, the resulting table for NormalizationData includes two references back to NormalizationPathMeasurement. I've traced it down to OneToManyPart.GetCollectionMapping(). In there, it is generating a column called NormalizationPathMeasurement_id, however, that isn't used when the data is inserted into the database.

I've included a thinned down project that re-produces the problem. Look in "NormalizationDataDbFixture.cs". There is no reason the test should fail, but by looking at the emitted SQL statements, you can tell something is wrong.

In fact, setting the NormalizationDataMap to set the column name makes it work...

        this.References(x => x.PathMeasurement)
            .Not.Nullable()
            .Column("NormalizationPathMeasurement_id")
            .Index("idx_NormalizationData_References");

Unfortinantly, it's not the column name I want.

Thanks.

  1. Support Staff 2 Posted by James Gregory on 23 Mar, 2010 09:50 PM

    James Gregory's Avatar

    The issue arises from two things: differences between your entity names and property names, and our current implementation of this mapping.

    The first, entity names and property names, goes like this: When you create a HasMany relationship, FNH looks at the containing class (NormalizationPathMeasurement in your case) and sticks an _id on the end. When you're creating a References, it looks at the property name and sticks an _id on. If your property name was NormalizationPathMeasurement instead of just PathMeasurement there wouldn't be an issue (or if your class was called PathMeasurement).

    That being said, we should be able to see that these two relationships represent a bi-directional relationship and should resolve the column names properly. So it's not really your fault.

    Right now, you can either rename your property, rename your class, or explicitly specify the column name.

    You were almost there with your column, except you needed to do it on the HasMany side instead. The References side is creating the correct column (property.Name + _id), it's the HasMany that's taking the containing class name and using that. What you need to do is use the KeyColumn method off the HasMany call.

    HasMany(x => x.DataPoints)
      .KeyColumn("PathMeasurement_id");
    
  2. 3 Posted by Peter Toms on 13 Apr, 2010 02:13 PM

    Peter Toms's Avatar

    Hi.

    A little "gotya" : The .KeyColumn represents the column name as relevant in the child table.

    Example

    public class SomeEntityMap : ClassMap

    {
        public SomeEntityMap ()
        {
    

    Table("TBL_SOMETABLE");

            Id(x => x.Id).GeneratedBy.Native("TBL_SOMETABLE_SEQ").Column("SomeEntity_ISN");
            References(x => x.SomeReference).Column("some_Column_in_the_db1");
            Map(x => x.something).Column("some_Column_in_the_db2");
            HasMany(x => x.Recipients)
              .Cascade.All()
              .Inverse()
              .KeyColumn("SomeEntity_ISN");
    

    } }

    Where SomeEntity_ISN is the column in the child table which references back to the parent.

    Oracle 10gR2 / Win2003 R2 / FNH 1.0.0.636

  3. Support Staff 4 Posted by James Gregory on 14 May, 2010 02:18 AM

    James Gregory's Avatar

    I've just committed revision d2f8f58, which includes some changes that should improve this situation. If a relationship can be determined as being bi-directional, FNH will grab the key columns from the many-to-one side of the relationship.

    I'm going to flag this as resolved. Please reopen if the latest changes don't work for you.

  4. James Gregory closed this discussion on 14 May, 2010 02:18 AM.

Comments are currently closed for this discussion. You can start a new one.