我正在尝试将表格frp,SQL Server 2005数据库映射到包含枚举的类:
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表示!
我希望有人可以解释我做错了什么,以及为什么会这样做呢?
由于
莫里斯
答案 0 :(得分: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()可能不错,并返回相应的枚举。
简单,功能强大,并且不会破坏您的模型以使用您的数据库。
答案 1 :(得分:1)
实现IUserType,然后为query.substitutions提供一个值以便于查询
<property name="query.substitutions">yes 'Y', no 'N', opt 'O'</property>
答案 2 :(得分:0)
我相信那是因为你试图将字符串映射到枚举。默认情况下,枚举类型的基类型是整数。
你可以使用像Nullable<bool>
这样的东西来实现你想要的东西,而不是枚举。但是,如果你真的想使用一个, AND 将支持字段保留为nchar(1)
列,我会进行如下查询:
SELECT intAddressSetting = CASE AddressSetting WHEN 'Y' THEN 1
WHEN 'N' THEN 0
ELSE -1
END
FROM table
并使用此字段映射到您的枚举。
根据需要更改值,通常“NO”值的值为0
,“YES”的值为1
,但在枚举中它们是相反的,Optional的值为{{ 1}},我将2
。
答案 3 :(得分:0)
我认为我偶然发现了另一种方法,这可能是也可能不是正确的方法。
正如我上面解释的那样,返回了ASCII代码值,因此对于Y,我得到的值为89,我将枚举扩展为使用这些值,如下所示:
public enum YesNoOptional { 是= 89, 不= 79, 可选= 78 }
这从数据库返回时正确填充值