流畅的NHibernate - 将实体映射为不同的类型

时间:2010-09-01 16:01:07

标签: fluent-nhibernate nhibernate-mapping

我有一个类,我想将其作为一个组件映射到包含它的任何表:

public class Time
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
}

我想将此类存储为数据库中的bigint - 与TimeSpan的存储方式相同,但我的类具有完全不同的行为,因此我决定创建自己的类。

我正在使用FLH的automapper并将此类设置为组件(其他类具有Time作为属性)。我已经创建了一个覆盖,但我不确定如何绘制它:

我试试这样:

public class TimeMappingOverride : IAutoMappingOverride<Time>
{
    public void Override(AutoMapping<Time> mapping)
    {
        mapping.Map(x => x.ToTimeSpan());
        mapping.IgnoreProperty(x => x.Hours);
        mapping.IgnoreProperty(x => x.Minutes);
        mapping.IgnoreProperty(x => x.Seconds);
    }
}

但得到了这个错误:

  

无法将“System.Linq.Expressions.UnaryExpression”类型的对象强制转换为“System.Linq.Expressions.MethodCallExpression”。

我应该怎么做?

2 个答案:

答案 0 :(得分:2)

有关组件的详细信息,请访问:http://wiki.fluentnhibernate.org/Fluent_mapping#Components

但首先,您无法映射方法。

假设您将ToTimeSpan()更改为属性AsTimeSpan,有两种方法可以执行此操作,因为您使用的是自动化,因此只有较难的方法适用于您:

  1. 创建ComponentMap<Time> - 完成后,您现有的映射就可以了。这与自动化不兼容。
  2. 内联声明组件映射:
  3. mapping.Component(x => x.AsTimeSpan, component => {  
        component.Map(Hours);  
        component.Map(Minutes);  
        component.Map(Seconds);  
        });
    

    不过,你每次都必须这样做。

    当然,这并未涉及“我希望将此课程存储为bigint ...”

    你是说你只想坚持几秒钟吗?如果是这样,请抓住顶部的所有内容,然后再次有两个选项:

    1. 实施NHibernate IUserType(呃)
    2. 创建一个私有属性或字段,仅将值存储为秒,并仅将其连接到NHibernate。公共属性的getter和setter必须转换为/秒。

答案 1 :(得分:0)

我个人还没有使用AutoMappings,但我的建议是调查NHibernate的IUserType来改变类型的持久化方式。我相信这是一种更清晰的方式来定义Time <-> bigint的自定义映射。

阅读上面的代码,Map(x => x.ToTimeSpan())将无效,因为您无法将应用程序到数据库转换代码嵌入到映射中。即使这是可能的,声明也会错过从数据库到应用程序的转换。另一方面,IUserType可以在NullSafeGetNullSafeSet方法中进行自定义转换。