使用NHibernate将nChar列映射到枚举类型

时间:2010-03-18 09:50:44

标签: c# sql-server nhibernate enums

我正在尝试将表格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表示!

我希望有人可以解释我做错了什么,以及为什么会这样做呢?

由于

莫里斯

4 个答案:

答案 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   }

这从数据库返回时正确填充值