2009-07-31 37 views
1

這是發佈在hibernate.org論壇和nhusers列表沒有太多運氣,所以我想我會在這裏嘗試。是否可以在nhibernate中使用sqlite清單打字功能?

簡單地說,假設我有一個類:

class A 
{ 
    public virtual object SomeValue { get; set; } 
} 

someValue中的類型基本上是在集.NET IConvertible類型(基元像布爾,字節,字符,INT16,雙,浮動等),加上byte []和字符串。

我正在嘗試爲A創建一個nhibernate映射來反映此 - 以便我可以基本上將SomeValue設置爲任意對象(以上類型之一)並稍後檢索它。然後我的applogic會反思它,找到相應的類型並進行相應的操作。

到目前爲止,我已經嘗試創建一個IUserType的實現來嘗試和處理這個。不過,我不知道該返回SqlType [] SqlTypes。我認爲新的SqlType(DbType.Object),但當我嘗試從這個生成模式時,我得到一個System.ArgumentException:方言不支持DbType.Object

如果我嘗試另一種數據類型,那麼我會得到各種轉換異常試圖轉換類型。例如,如果我使用DbType.Binary,並將someValue設置爲一個int32,在嘗試提交時,我得到System.InvalidCastException:無法將類型'System.Int32'的對象類型轉換爲'System.Byte []'。

有沒有辦法做到這一點?

下面

附代碼IUserType的非工作實現(基於http://intellect.dk/post/Implementing-custom-types-in-nHibernate.aspx

public class DataElementType : IUserType 

    { 
     SqlType baseType = new SqlType(DbType.Binary); 
     public SqlType[] SqlTypes 
     { 
      get 
      { 
       return new[] { baseType }; 
      } 
     } 

     public System.Type ReturnedType 
     { 
      get { return typeof(object); } 
     } 

     public new bool Equals(object x, object y) 
     { 
      if (x == null) 
       return false; 
      else 
       return x.Equals(y); 
     } 

     public int GetHashCode(object x) 
     { 
      return x.GetHashCode(); 
     } 

     public object NullSafeGet(IDataReader rs, string[] names, object owner) 
     { 
      return rs[names[0]]; 
     } 

     public void NullSafeSet(IDbCommand cmd, object value, int index) 
     { 
      var param = new SQLiteParameter(baseType.DbType, value); 
      cmd.Parameters.Insert(index, param); 
     } 

     public object DeepCopy(object value) 
     { 
      if (value == null) return null; 
      return value; 
     } 

     public bool IsMutable 
     { 
      get { return false; } 
     } 

     public object Replace(object original, object target, object owner) 
     { 
      return original; 
     } 

     public object Assemble(object cached, object owner) 
     { 
      return cached; 
     } 

     public object Disassemble(object value) 
     { 
      return value; 
     } 
    } 
+0

Ooo ...你正在嘗試做一些棘手的事情。祝你好運:你冒險進入複雜的水域。 – 2009-08-03 01:15:22

回答

1

事實證明,讓周圍的SQLTYPE(DbType.Object)問題是由方言不支持,我們做它通過明確的支持繼承的SQLiteDialect支持:

public class SQLiteDialectWithManifestTyping : SQLiteDialect 
{ 
    public SQLiteDialectWithManifestTyping() : base() 
    { 
     base.RegisterColumnType(DbType.Object, "NONE"); 
    } 
} 

要流利使用這種方言,您SQLiteConfiguration對象調用方言()。在NHibernate中,設置適當的配置屬性dialect(參見ref手冊的3.5.1節)。

然後我們就可以應用上述DataElementType實現我們的映射(需要改變的SQLType定義是:

public SqlType[] SqlTypes 
    { 
     get 
     { 
      return new[] { new SqlType(DbType.Object) }; 
     } 
    } 

注:

  1. 它不是完美有一種趨勢將所有離散數字向上轉換爲Int64並浮點數加倍

  2. 沒有隱式的方式來存儲大的無符號值(例如ulong > = long.MaxValue),但這是一個普通的sqlite問題(可能是一個普通的ado.net問題?)。

  3. 由於缺少編譯時檢查,可能需要在NullSafeSet方法中進行一些運行時檢查,以確保該值是基本類型。嘗試存儲常規對象似乎只會導致調用對象的ToString()方法。

相關問題