Question

Using NH 2.0, I have a custom type. It is composed of four properties, so I implemented ICompositeUserType.

I want to specify length and precision for the string and decimal properties within the user type, to avoid specifying it with every usage in the mapping files.

But there is only a PropertyTypes property to implement, which returns IType. The funny thing is, the IUserType has a SqlTypes property, ICompositeUserType does not.

  • Do I have to implement both interfaces?
  • Do I have to implement a user type to wrap each sql-type I want to specify?
  • Or how can I specify the Sql type for a composite user type?

Thanks a lot.

Was it helpful?

Solution 2

I found the solution, it is pretty simple. I have to create the NHibernate types using the TypeFactory:

public IType[] PropertyTypes
{
  get
  {
    return new []
    {
      TypeFactory.GetDecimalType(36, 18),
      TypeFactory.GetStringType(100)
    }
  }
}

OTHER TIPS

I recommend downloading source code for this type of digging (NH 2.0).

First take a look at TypeFactory.HeuristicType method, which builds the IType instance.

...
else if (typeof(ICompositeUserType).IsAssignableFrom(typeClass))
{
    type = new CompositeCustomType(typeClass, parameters);
}
else if (typeof(IUserType).IsAssignableFrom(typeClass))
{
    type = new CustomType(typeClass, parameters);
}
...

So if your custom type implements ICompositeUserType it gets instantiated as CompositeCustomType class. This eliminates the possibility to implement both ICompositeUserType and IUserType interfaces.

Now let's take a look into CompositeCustomType

public override SqlType[] SqlTypes(IMapping mapping)
{
    IType[] types = userType.PropertyTypes;
    SqlType[] result = new SqlType[GetColumnSpan(mapping)];
    int n = 0;
    for (int i = 0; i < types.Length; i++)
    {
        SqlType[] sqlTypes = types[i].SqlTypes(mapping);
        for (int k = 0; k < sqlTypes.Length; k++)
        {
            result[n++] = sqlTypes[k];
        }
    }
    return result;
}

So it takes your types returned from PropertyTypes and builds the SqlType for each property. This means that providing your own user type wrappers for each property will do the trick.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top