2010-03-18 72 views
0

我试图映射表FRP,一个SQL Server 2005数据库,其包含一个枚举类:使用NHibernate的NCHAR列映射到一个枚举类型

public class MyClass{ 
private YesNoOptional addressSetting; 
public YesNoOptional AddressSetting{ 
    {get; set;} 
} 

}

public enum YesNoOptional { 
    Yes, 
    No, 
    Optional 
} 

这将决定将三个值中的一个插入相应的列 - 'Y','N','O'。此列的类型为nchar(1)。

我的映射文件是像这样(addressSetting是这是导致问题的属性):使用配置上面我收到以下错误

<class name="IncidentDefinition" table="IR_INCIDENT_DEF" lazy="false" > 
    <id name="Guid" column="INT_GUID" > 
     <generator class="guid"></generator> 
    </id> 
    <property name="Reference" column="INT_REF" ></property> 
    <property name="Description" column="INT_DESCRIPTION" ></property> 

    <property name="AddressSetting" column="INT_ADDRESS_REQ" ></property> 

    <property name="Active" column="INT_ACTIVE" type="YesNo"></property> 
    <property name="PinDocId" column="INT_PIN_DOC_ID"></property> 
    </class> 

: NHibernate.ADOException:无法初始化集合: System.FormatException:输入字符串的不正确的格式..

如果我尝试使用如自定义类型,因此映射枚举:

<property name="AddressSetting" column="INT_ADDRESS_REQ" type="ML.Types.YesNoOptional, ML.Types" ></property> 

错误:System.FormatException:输入字符串的格式不正确。

接下来,如果我尝试使用像一个特定类型的,以便:

<property name="AddressSetting" column="INT_ADDRESS_REQ" type="String" ></property> 

产生此错误:NHibernate.PropertyAccessException:该System.String类型不能被分配给类型System.ArgumentException的属性:类型“System.String”的对象不能转换为类型“ML.Types.YesNoOptional” ..

作为最后一招我试图指定类型,像这样一个char:

<property name="AddressSetting" column="INT_ADDRESS_REQ" type="Char" ></property> 

这个效果稍好一些,因为它不会抛出错误,但是不是从表中返回字符并将其映射到枚举类型,而是返回字符的ASCII值 - 所以Y由89表示!

我希望有人能解释我做错了什么,或者为什么会发生这种情况?

感谢

莫里斯

回答

1

你可能会考虑创建此定制IUserType返回正确填充值。我写了一篇关于与DateTime做类似的博客文章,你可以复制粘贴90%的代码:http://blog.statichippo.com/archive/2010/01/07/calendar-sizes-datetime-vs-nullable-sqldatetime-in-nhibernate.aspx

基本上,最大的变化是在NullSafeSet和NullSafeGet。在NullSafeSet中,您需要对枚举进行切换,然后相应地将DB值设置为Y/N/O。而在你的NullSafeGet中,你会想要做一个开关结果(可能不是一个坏主意先运行Char.ToLower())并返回相应的枚举。

简单,功能强大,它不会破坏你的模型来处理你的数据库。

0

我相信那是因为你试图映射一个字符串的枚举。默认情况下,枚举类型的基类型是一个整数。

可能使用类似Nullable<bool>来实现你想要的,而不是一个枚举。但是,如果你真的想用一个,保持支持字段作为nchar(1)专栏中,我会做一个查询,如:

SELECT intAddressSetting = CASE AddressSetting WHEN 'Y' THEN 1 
               WHEN 'N' THEN 0 
               ELSE -1 
          END 
FROM table 

,并使用此申请映射到你的枚举。

根据需要更改值,通常是“NO”值有0和值“YES”是1但在你的枚举他们逆转,可选有2的值,我会做一个-1

+0

谢谢,但我是新来NHibernate和你能告诉我在哪里编辑SQL要做到这一点,请? – Morrislgn 2010-03-18 10:45:17

0

我认为我偶然发现了另一种方式来做到这一点,这可能或可能不是正确的做法。

正如我上面的ASCII代码值解释返回,所以对于YI渐渐的89值I扩展到使用这些值,像这样的枚举:

公共枚举YesNoOptional { 是= 89, 否= 79, 可选= 78 }

这当他们从数据库

+0

我认为当你开始让你的代码反映你的数据库时,你会走上一条可怕的道路 – hackerhasid 2010-03-19 18:05:12

1

实现一个IUserType,然后给出一个值query.substitutions查询方便

<property name="query.substitutions">yes 'Y', no 'N', opt 'O'</property> 
+0

对不起,因为延迟回复。感谢帮助的人,尝试了这些解决方案,这些看起来比我的黑客攻击符合ASCII db值的想法要好得多。 – Morrislgn 2010-03-24 10:47:55