Using ICompositeUserType in different tables with different column names

I am trying to customize the display of NHibernate ICompositeUserType. But I was stuck trying to make the implementation general, sufficient for use in different tables.

Our old database has many tables with latitudes and longitudes, and I want to map them in my domain objects as the Position class. The problem is that each table has different names for the latitude and longitude columns.

I created an implementation of ICompositeUserType, but it seems that I need to set the property names to the column names in the table, which means that I cannot use CustomType for different tables (with different column names).

I thought I should set PropertyNames to property names in my Position class and map them to table columns in my ClassMap, but this seems to throw an NHibernate exception:

NHibernate.MappingException: property mapping has wrong number of columns

It seems like I'm doing something wrong in my comparison, but I can't figure it out.

Here is the code snippet from my ICompositeUserType:

public class PositionUserType : ICompositeUserType
{
  private readonly IType[] _propertyTypes = 
     new [] { NHibernateUtil.Double , NHibernateUtil.Double };

  private readonly string[] _propertyNames = 
     new[] { "Latitude", "Longitude"  };

  public string[] PropertyNames { get { return _propertyNames; } }

  public IType[] PropertyTypes { get { return _propertyTypes; } }

  // Other methods omitted
}

and my class map:

public class LastPositionMap : ClassMap<LastPosition>
{
    public LastPositionMap()
    {
        Map(p => p.Position)
            .Columns.Add("LPLongitude", "LPLongitude")
            .CustomType(typeof(PositionUserType));

        // Other mapping omitted
    }
}

and class Position

public class Position
{
  public double Latitude { get; private set; }
  public double Longitude { get; private set; }

  public Position(double latitude, double longitude)
  {
    Latitude = latitude;
    Longitude = longitude;
  }
}

I currently have a job where I can use the Component floating card, but that means my Position class should be mutable, and I would prefer it to be different.

Can anyone help? I looked at a few articles and books well, but I still can't get it to work.

Thank,

Adam

+3
source share
2 answers

, :

public class LastPositionMap : ClassMap<LastPosition>
{
    public LastPositionMap()
    {
        Map(p => p.Position)

            // Clear the columns to get rid of Fluent NH default column names
            .Columns.Clear()

            .ColumnsAdd("LPLongitude", "LPLongitude")
            .CustomType(typeof(PositionUserType));

        // Other mapping omitted
    }
}

, Fluent NH , , .

XML- ( Mappings.ExportTo() ), , , - :

<property <!-- details here -->
  <column name="Latitude" /> 
  <column name="Longitude" /> 
  <column name="LPLongitude" /> 
  <column name="LPLatitude" /> 
</property>

:

<property <!-- details here -->
  <column name="LPLatitude" /> 
  <column name="LPLongitude" /> 
</property>
+4

, backingfield

Component(x => x.Position, c =>
    {
        c.Map(p => p.Longitude, "LPLongitude").Access.BackingField();
        c.Map(p => p.Latitude, "LPLatitude").Access.BackingField();
    })

, , ,

protected Position() { } // to make NHibernate default implementation happy

Position default(double)

+2

Source: https://habr.com/ru/post/1735029/


All Articles