我有一個遺留應用程序,數據庫中有一個可爲空的DateTime列 - NULL值用於表示+ Infinity。我的應用程序使用相當標準的NHibernate + DDD設置,包括Fluent-NHibernate和Linq2NHib。映射和查詢UserTypes - 數據庫中的可爲空數據庫爲不可空區域
我們假設我有以下代表實體的C#類。
class Discount
{
DateTime? ExpirationDate { get; set; }
// ... etc.
}
原來有管理這個ExpirationDate
,我想封裝,例如,它必須是在午夜,並且可以有Infinity
值的規則。在傳統應用NULL == Infinity
中就像在數據庫中一樣。我想將它轉化成一些更喜歡這組類:
class Discount
{
OpenBusinessDate ExpirationDate { get; set; } // assume not nullable
}
class OpenBusinessDate // immutable
{
private DateTime _Value;
private bool _IsInfinity;
OpenBusinessDate(DateTime? value)
{
if (null == value)
{
_IsInfinity = true;
_Value = DateTime.MaxValue; // or SqlDateTime.MaxValue if you must
}
else
{
ErrorIfNotMidnight(value);
_Value = value;
}
}
DateTime ToDateTime() { return _Value; }
// ... casters, comparison methods, etc...
}
我目前沒有對所有現有的空值轉換成數據庫,以恆定的選項,但我喜歡我的域內查詢這樣的事情...
IList<Discount> GetAll(OpenBusinessDate expiringAfterDate)
{
return (from d in session.Linq<Discount>()
where d.ExperationDate > expiringAfterDate
select d).ToList();
}
...並已NH知道翻譯成這個......
SELECT * FROM Discount
WHERE (ExpirationDate IS NULL
OR ExpirationDate > @expiringAfterDate)
/* ...or possibly this... */
SELECT * From Discount
WHERE (COALESCE(ExpirationDate, '9999-12-31') > @expiringAfterDate)
我一直在服用的NH看看用戶類型,並已取得了IUserType來轉換fr om Infinity
到NULL
並返回(與實際的DateTime一起),但我還沒有發現如何讓查詢被寫入像我想要的。也就是說,現在,上面的LINQ和我的代碼會生成查詢:
SELECT * FROM Discount
WHERE (ExpirationDate > 'Infinity')
/* b/c OpenBusinessDate.ToString() on Infinity
produces "Infinity" for debugging purposes */
沒有人有哪裏看或具有類似工作的例子有什麼建議?我似乎無法找到正確的一組關鍵字來找到匹配的東西,我認爲這是一個解決的問題。這純粹是一個NH問題要解決,還是這也會涉及Linq2NH的一些工作?
這種類型的日期適用於我的域中的大量實體,我真的不想在每個查詢中重複「或null」檢查。它已經在過去造成了錯誤,並且使我必須重複更多的測試用例。但是,我沒有想過只使用DateTime的後臺?如果我做不好,這可能是一個很好的妥協。 – xero 2011-02-16 02:41:33