2010-03-18 103 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