C# 映射和查询UserTypes-在DB中可为null到在域中不可为null

C# 映射和查询UserTypes-在DB中可为null到在域中不可为null,c#,nhibernate,nhibernate-mapping,linq-to-nhibernate,C#,Nhibernate,Nhibernate Mapping,Linq To Nhibernate,我有一个遗留应用程序,数据库中有一个可空的DateTime列-空值用于表示+无穷大。我的应用程序使用相当标准的NHibernate+DDD设置,包括Fluent NHibernate和Linq2NHib 让我们假设我有以下表示实体的C类 class Discount { DateTime? ExpirationDate { get; set; } // ... etc. } 事实证明,我想封装一些规则来管理这个过期日期,例如,它必须在午夜,并且可以有无穷大的值。在传统应用程序中

我有一个遗留应用程序,数据库中有一个可空的DateTime列-空值用于表示+无穷大。我的应用程序使用相当标准的NHibernate+DDD设置,包括Fluent NHibernate和Linq2NHib

让我们假设我有以下表示实体的C类

class Discount
{
    DateTime? ExpirationDate { get; set; }
    // ... etc.
}
事实证明,我想封装一些规则来管理这个过期日期,例如,它必须在午夜,并且可以有无穷大的值。在传统应用程序中,NULL==无穷大,就像在DB中一样。我想把它转换成更像这组类的东西:

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中的用户类型,并制作了一个IUserType来从无穷大转换为NULL,然后与实际的DateTime一起返回,但我还没有发现如何按照我想要的方式编写查询。也就是说,现在,上面的Linq和我的代码将生成查询:

SELECT * FROM Discount
WHERE (ExpirationDate > 'Infinity')
/* b/c OpenBusinessDate.ToString() on Infinity 
   produces "Infinity" for debugging purposes */

有没有人对去哪里找有什么建议,或者有一个类似的工作示例?我似乎找不到合适的关键字集来查找与我认为已解决的问题相匹配的内容。这纯粹是一个NH问题需要解决,还是这也会涉及到Linq2NH的一些工作?

我的做法是为ExpirationDate映射一个受保护的属性,然后为OpenBusinessDate公开一个公共只读属性,如下所示:

public class Discount
{
    private DateTime _value;
    protected DateTime? ExpirationDate 
    {
        get { return _value; }
        set { 
                _value = value; 
                ExpirationDate = new OpenBusinessDate(value); 
            }
    }
    public OpenBusinessDate OpenExpirationDate {get; private set;}
}
然后重写折扣类的映射,如下所示:

public PersonMap : ClassMap<Discount>
{  
    public PersonMap()  
    {  
        Map(Reveal.Property<Discount>("ExpirationDate ")) 
    }  
}
然后在linq查询中,您将能够像这样应用无限逻辑

 return (from d in session.Linq<Discount>
           where d.ExpirationDate > expiringAfterDate || d.ExpirationDate != null
           select d).ToList();

这种类型的日期适用于我的域中大量的实体,我真的不想在每个查询中重复或null检查。它在过去已经引起了错误,并且使我不得不重复更多的测试用例。然而,我没有想到只使用DateTime?的支持字段?。如果我做不好的话,那可能是一个很好的妥协。
 return (from d in session.Linq<Discount>
           where d.ExpirationDate > expiringAfterDate || d.ExpirationDate != null
           select d).ToList();