流畅的NHibernate组件映射 - 字符串DB传递给工厂的值产生所需的对象类型

时间:2009-04-16 18:53:07

标签: nhibernate fluent-nhibernate

表:

CREATE TABLE Instrument
(   Id              INT IDENTITY
,   Name            VARCHAR(50)
,   Tenor           VARCHAR(10)
//...

型号:

    interface ITenor
    {
        int Length { get; }
        string ToString();
    }

    class DayTenor : ITenor
    {
        public int Length
        {
            get { return 1; }
        }

        public override string ToString()
        {
            return "DAY";
        }
    }

    class MonthTenor : ITenor
    {
        public int Length
        {
            get { return 30; }
        }

        public override string ToString()
        {
            return "MONTH";
        }
    }

    class TenorFactory
    {
        ITenor GetTenor(string tenorString)
        {
            switch (tenorString)
            {
                case "DAY":
                    return new DayTenor();
                    break;
                case "MONTH":
                    return new MonthTenor();
                    break;
                default:
                    throw new NotImplementedException(string.Format( "Tenor {0} is not implemented", tenorString ));
            }
        }
    }

    class Instrument
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ITenor Tenor { get; set; }
    }

    class InstrumentMap : ClassMap<Instrument>
    {
        public InstrumentMap()
        {
            WithTable( "Instrument" );
            Id( x => x.Id );
            Map( x => x.Name );
            Map( x => x.Tenor );
        }
    }

这是问题域的一个很好的简化。

Map( x => x.Tenor );显然不起作用,因为您无法将VARCHAR列隐式转换为ITenor类型。有没有办法可以映射以自动使用Factory来获取DB中指定字符串所需的ITenor,并使用ITenor类中的ToString()恢复到DB?

如果没有,您会建议进行哪些重构以使其可行?非常感谢

1 个答案:

答案 0 :(得分:2)

一种可能的解决方案是将字符串保留在数据库中,并将其映射到TenorString属性。然后添加另一个类型属性,它只是在字符串和键入的值之间进行转换:

class Instrument
{
    public string TenorString { get; set; }
    public ITenor Tenor { 
        get { return GetTenor(this.TenorString); } 
        set { TenorString = value.ToString() }; 
    }
}

TenorString是正常映射的,但Tenor属性根本没有映射:

Map( x => x.TenorString );

当然,Tenor get属性可以返回一个缓存值,当TenorString发生更改时会重置该值以避免每次都出现工厂调用。