5

我正在處理一些遺留數據庫,其中某些表中的日期和時間字段分別爲char(8)列(格式爲yyyyMMdd和HH:mm:ss)。如何將2個char列映射到單個.NET DateTime屬性?我曾嘗試以下,但我得到理所當然的「不能訪問二傳手」的錯誤,因爲日期時間和日期的TimeOfDay屬性是隻讀的:如何使用NHibernate(Fluent)將DateTime屬性映射到數據庫中的2個varchar列?

public class SweetPocoMannaFromHeaven 
{  
    public virtual DateTime? FileCreationDateTime { get; set; } 
} 

mapping.Component<DateTime?>(x => x.FileCreationDateTime, 
      dt => 
      { 
       dt.Map(x => x.Value.Date, 
        "file_creation_date"); 
       dt.Map(x => x.Value.TimeOfDay, 
        "file_creation_time"); 
      }); 

我也試圖定義DATETIME一個IUserType,但我不能弄明白。我已經做了大量的谷歌搜索答案,但我仍然無法弄清楚。什麼是我最好的選擇來處理這個 愚蠢的 遺留數據庫約定?一個代碼示例會很有幫助,因爲在這些更加模糊的場景中沒有太多的文檔。

回答

8

您需要一個ICompositeUserType才能處理多個列。您需要加強錯誤檢查,解析格式等,但這是您的起點。

HTH,
Berryl

public class LegacyDateUserType : ICompositeUserType 
{ 

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

    public int GetHashCode(object x) { 
     return x == null ? typeof (DateTime).GetHashCode() + 473 : x.GetHashCode(); 
    } 

    public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner) 
    { 
     if (dr == null) return null; 

     var datePortion = NHibernateUtil.String.NullSafeGet(dr, names[0], session, owner) as string; 
     var timePortion = NHibernateUtil.String.NullSafeGet(dr, names[1], session, owner) as string; 

     var date = DateTime.Parse(datePortion); 
     var time = DateTime.Parse(timePortion); 
     return date.AddTicks(time.Ticks); 
    } 

    ///<summary> 
    /// Write an instance of the mapped class to a prepared statement. Implementors 
    /// should handle possibility of null values. A multi-column type should be written 
    /// to parameters starting from index. 
    ///</summary> 
    public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session) { 
     if (value == null) { 
      // whatever 
     } 
     else { 
      var date = (DateTime) value; 
      var datePortion = date.ToString("your date format"); 
      NHibernateUtil.String.NullSafeSet(cmd, datePortion, index, session); 
      var timePortion = date.ToString("your time format"); 
      NHibernateUtil.String.NullSafeSet(cmd, timePortion, index + 1, session); 
     } 
    } 

    public object GetPropertyValue(object component, int property) 
    { 
     var date = (DateTime)component; 
     return property == 0 ? date.ToString("your date format") : date.ToString("your time format"); 
    } 

    public void SetPropertyValue(object component, int property, object value) 
    { 
     throw new NotSupportedException("DateTime is an immutable object."); 
    } 

    public object DeepCopy(object value) { return value; } 

    public object Disassemble(object value, ISessionImplementor session) { return value; } 

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

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

    ///<summary>Get the "property names" that may be used in a query.</summary> 
    public string[] PropertyNames { get { return new[] { "DATE_PORTION", "TIME_PORTION" }; } } 

    ///<summary>Get the corresponding "property types"</summary> 
    public IType[] PropertyTypes { get { return new IType[] { NHibernateUtil.String, NHibernateUtil.String }; } } 

    ///<summary>The class returned by NullSafeGet().</summary> 
    public Type ReturnedClass { get { return typeof(DateTime); } } 

    ///<summary>Are objects of this type mutable?</summary> 
    public bool IsMutable { get { return false; } } 

} 

===流利映射(假設自動映射W/override類)====

public void Override(AutoMapping<MyClass> m) 
{ 
    .... 
    m.Map(x => x.MyDateTime).CustomType<LegacyDateUserType>(); 
} 
+1

將這個映射是什麼樣的?我創建了一些IUserType實現,但總是針對單個屬性/列對。我想知道在什麼情況下,'''''數組會有多個元素。 – 2010-03-27 14:22:00

+0

嗨傑米。您只需將該屬性關聯到自定義類型;在FNH中,它看起來像我添加到我的文章末尾的代碼行一樣簡單。如果自定義類型是普遍的,你也可以設置一個約定來處理它。歡呼聲 – Berryl 2010-03-27 14:36:18

+0

這看起來不錯! thx多!我會在稍後開始工作時嘗試它,並根據我的測試將其設置爲答案。 – gabe 2010-03-29 11:53:05

相關問題