2010-05-20 151 views
6

我有一個使用Criteria的nHibernate查詢,並且我試圖在查詢本身中將字符串轉換爲bool。我已經做了與鑄造一個字符串爲int相同,而且效果很好(以下簡稱「數據字段」屬性爲「1」作爲一個字符串):使用nHibernate標準將字符串轉換爲bool標準

var result = Session 
    .CreateCriteria<Car>() 
    .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.Int32, 
    Projections.Property("DataField"), 1)) 
    .List<Car>(); 

tx.Commit(); 

但我試圖做同樣的布爾,但我沒有得到期望的結果:

var result = Session 
    .CreateCriteria<Car>() 
    .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.bool, 
    Projections.Property("DataField"), true)) 
    .List<Car>(); 

tx.Commit(); 

「數據字段」是字符串「真」,但結果在一個空的列表,其中應包含與設置爲「數據字段」屬性字符串100個元素「真」。我嘗試過使用字符串「true」和「1」,但結果仍然是一個空列表。

[編輯]

如下評論,我可以檢查字符串「真」或「假」,但我會說這是不僅僅是一個布爾一個更具普遍性的問題。

請注意,這個想法是有某種鍵值表示的數據,其中的值可以是不同的數據類型。我需要值表來包含所有數據,因此將數據存儲爲字符串似乎是最乾淨的解決方案!

我已經能夠使用上面的方法來存儲int和double作爲字符串,並在查詢中強制轉換,但我沒有成功使用DateDime和Boolean的相同方法。

而對於DateTime,實際的DateTime對象是至關重要的。

如何將字符串轉換爲布爾值,並將字符串轉換爲DateTime在查詢中工作?

感謝

+1

我不明白爲什麼不只是'Restrictions.Eq(「DataField」,「True」)' – 2010-05-20 20:27:14

+0

你是對的。對於布爾值,我可以輕鬆地進行字符串比較,但是對於DateTime,我有和bool相同的問題,並且將字符串強制轉換爲DateTime對象是至關重要的 – 2010-05-21 08:04:23

+0

爲什麼您將datetime字段映射爲字符串? – 2010-05-21 13:44:22

回答

5

不幸的是,你要實現的目標是什麼將是很難做到的,因爲它違背了什麼樣的NHibernate和RDBMS中試圖爲你做糧食。通過使用無類型數據,您將避開使用RDBMs帶來的許多收益。

沒有完整的模式,我只能猜測。你怎麼知道這個領域的正確類型是什麼?我猜你有一個'type'列,指示該值是否爲整數,布爾值,日期等。如果是這樣,繼續使用類型標識符列,併爲每個數據類型加上單獨的列。這並不比你在做什麼複雜,因爲對於每種數據類型已經有了單獨的查詢,並且你可以清楚地看到類型檢查和索引的可能性。

如果要防止定義多個值的可能性(即多個類型列中的值),則可以在該表上創建一個約束來驗證每個行僅爲最多一個數據類型定義了一個值。 (您也可以驗證指定類型的列是否爲空,如果這適合您的情況。)

更改後,您可以讓nHibernate管理不同的類型,並讓它爲您完成所有繁重的工作。 NHibernate的可以映射類hiearchies對錶,所以你可以創建這樣的實體:

public class AbstractProperty 
{ 
    // concrete name - persisted 
    public String Name { get; set; etc.. } 

    // owner property as well? 

    // abstract value provided by subclasses. This property is not persisted. 
    // used simply to provide polymorphic access to the value. 
    public abstract Object Value { get; set; } 
} 

public class DateProperty : AbstractProperty 
{ 
    // concrete date property 
    public Date date { get; set; etc.. } 

    // value delegates to date property 
    public Object value { get; set; } 
} 

有了這個計劃,你必須與特定的數據類型,其中,例如,查詢使用檢索值的選項DateProperty實體明確返回DateProperty實例。您還可以編寫可能返回多種類型的查詢,其中靜態類型爲AbstractProperty。然後,您可以使用visitor pattern或AbstractProperty上的'is'檢查來確定類型並將其轉換爲具體類型以獲取該值。

一位nHibernate專家可能能夠幫助您修復演員陣容,但從長遠來看,我建議在您的數據庫中使用真實的數據類型。它會在以後節省您的頭痛。

+0

感謝您的好評。我會研究你的解決方案! – 2010-05-23 13:32:54

+1

這也是我所建議的;在hibernate中使用繼承可以查詢任何通用屬性,但是您可以爲每個類型提供一個表,並在模式中使用適當類型的列。 – RMorrisey 2010-05-28 18:40:11