How to map Type with Nhibernate (and Fluent NHiber

2019-07-15 05:06发布

问题:

Let's say I have something similar to this :

public class DataType
{
    //For NHibernate
    private DataType(){}

    public DataType(string name, Type type, string defaultValue)
    {
        Name = name;
        TypeOfContent = type;
        DefaultInvariantStringValue = defaultValue;
    }

    public string Name { get; set; }
    public Type TypeOfContent { get; set; }
    public string DefaultInvariantStringValue { get; set; }
}

How do I map the property TypeOfContent with NHibernate (fluent mapping would be appreciated too)?

I would constrain Type to C# Built-In Types e.g. string, int, datetime, etc. So I would like to store System.String (for a string) in the database

回答1:

I'm curious, why don't you do this instead

public class DataType
{       
    ...        
    private string _typeOfContent;
    public virtual Type TypeOfContent
    {
        get { return Type.GetType(_typeOfContent); }
        set { _typeOfContent = value.FullName; }
    }   
}

...

public class DataTypeMap : ClassMap<DataType>
{
    Map(x => x.TypeOfContent)
       .Access.CamelCaseField(Prefix.Underscore)
       .CustomType<string>();
}


回答2:

I'm wondering if this is being overthought a little. Can you not simply map the type as a property?

public class DataTypeMap : ClassMap<DataType>
{
   public DataTypeMap()
   {
      // ...
      Map(x => x.TypeOfContent);
   }
}

In sqlite at least this will map to a TEXT column which will store the AssemblyQualifiedName.

The relevant hbm.xml is here:

<property name="Type" type="System.Type, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Type" />
</property>

The additional question of how to elegantly map the default value is also of interest to me. In sqlite at least there is no 'strong-typing' of a column (I am probably using the wrong terminology, see the link) so at the database level at least it should be possible to simply have an object DefaultValue and persist/depersist without loss of precision. However, it remains an open question as to how to create a mapping for this that NHibernate will understand.



回答3:

I will try to answer my own question but I hope there's another (easier/cleaner) way.

I think I could change the type of the property TypeOfContent to something like BuiltInType (a custom Type wrapper class) so it could implement IUserType.

I could then use this technique : http://blog.jagregory.com/2009/01/11/fluent-nhibernate-auto-mapping-type-conventions/

Edit 1: I don't like this solution cause it forces me to add a dependency (IUserType) on NHibernate on my model.