2008-10-28 93 views
12

我有一个Oracle数据库,其中一个字段是日期范围字段。它基本上只是以YYYY/MM/DD-YYYY/MM/DD的格式存储在数据库中的VARCHAR(40)。我想它在NHibernate的映射到我有这样nHibernate映射到自定义类型

public class DateTimeRange 
{ 
    public DateTimeRange(DateTime fromTime, DateTime toTime) 
    { 
     FromTime = fromTime; 
     ToTime = toTime; 
    } 

    public override string ToString() 
    { 
     return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss")); 
    } 

    public DateTime FromTime { get; set; } 

    public DateTime ToTime { get; set; } 
} 

创建一个自定义类我该如何映射到这样的自定义类?

回答

17

您需要实现您自己的IUserType。

有关详细信息,请参阅此blog post。我还会粘贴下面的相关部分以防博客消失。

在NHibernate中,自定义映射类型是一个派生自IUserType或ICompositeUserType接口的类。这些接口包含了几个必须实现的方法,但为了我们的目的,我们将重点介绍其中的两个。考虑以下。

public class TypeClassUserType : IUserType 
    { 


    object IUserType.NullSafeGet(IDataReader rs, 
     string[] names, 
    object owner) { 

    string name = NHibernateUtil.String.NullSafeGet(rs, 
    names[0]) as string; 

    TypeClassFactory factory = new TypeClassFactory(); 
    TypeClass typeobj = factory.GetTypeClass(name); 
    return typeobj; 
    } 

    void IUserType.NullSafeSet(IDbCommand cmd, 
    object value, 
    int index) { 

     string name = ((TypeClass)value).Name; 
    NHibernateUtil.String.NullSafeSet(cmd, name, index); 
    } 
    } 

已经创造了这个班,我现在可以明确地ActualClass和类型类之间的关联映射为在ActualClass映射一个简单的属性。

<property 
    name="Type" 
    column="TypeName" 
    type="Samples.NHibernate.DataAccess.TypeClassUserType, 
     Samples.NHibernate.DataAccess" /> 

由于NHibernate的是节省ActualType实例的过程中,它会加载和创建TypeClassUserType的一个新的实例,并调用NullSafeSet方法。从方法体中可以看到,我只是从映射属性中提取名称(作为值参数传入),并将提取的名称设置为要在数据库中设置的参数的值。最终的结果是,虽然ActualClass的Type属性在领域模型中是TypeClass,但只有TypeClass对象的Name属性存储在数据库中。反过来也是如此。当NHibernate从数据库中加载ActualType的一个实例并找到我的自定义映射类型的属性时,它加载我的自定义类型并调用NullSafeGet方法。如您所见,我的方法从返回的数据中获取名称,调用我的flyweight工厂以获取TypeClass的正确实例,然后实际返回该实例。类型解析过程对我的数据访问类(甚至对于NHibernate本身而言)是透明的。

+0

嗨TheSoftwareJedi,请你帮忙检查你在帖子中提到的链接?它没有找到。你能给我一个可用的链接。谢谢。 – 2014-03-05 01:37:57