简体   繁体   English

如何使用NHibernate(Fluent)将DateTime属性映射到数据库中的2个varchar列?

[英]How do you map a DateTime property to 2 varchar columns in the database with NHibernate (Fluent)?

I'm dealing with a legacy database that has date and time fields as char(8) columns (formatted yyyyMMdd and HH:mm:ss, respectively) in some of the tables. 我正在处理一个遗留数据库,它在一些表中将日期和时间字段作为char(8)列(分别格式化为yyyyMMdd和HH:mm:ss)。 How can i map the 2 char columns to a single .NET DateTime property? 如何将2个char列映射到单个.NET DateTime属性? I have tried the following, but i get a "can't access setter" error of course because DateTime Date and TimeOfDay properties are read-only: 我尝试了以下内容,但我得到了“无法访问setter”错误,因为DateTime Date和TimeOfDay属性是只读的:

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");
            });

I have also tried defining a IUserType for DateTime, but i can't figure it out. 我也尝试过为DateTime定义一个IUserType,但我无法理解。 I've done a ton of googling for an answer, but i can't figure it out still. 我已经做了大量的谷歌搜索,但我还是无法弄明白。 What is my best option to handle this stupid legacy database convention? 处理这个 愚蠢的 遗留数据库约定的最佳选择是什么? A code example would be helpful since there's not much out for documentation on some of these more obscure scenarios. 一个代码示例会有所帮助,因为对于一些这些更加模糊的场景的文档并不多。

You need an ICompositeUserType to handle more than one column. 您需要ICompositeUserType来处理多个列。 You need to beef up the error checking, parsing formats, etc, but here is a starting point for you. 您需要加强错误检查,解析格式等,但这里是您的起点。

HTH, HTH,
Berryl 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; } }

}

=== fluent mapping (assuming automapping w/override classes) ==== ===流畅的映射(假设自动化w / override类)====

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用流畅的NHibernate将枚举映射为int值? - How do you map an enum as an int value with fluent NHibernate? 如何使用Fluent NHibernate映射实体 - &gt;接口关系? - How do you map an entity -> interface relationship using Fluent NHibernate? 在Fluent NHibernate中,如何映射组件列表? - In Fluent NHibernate, how do you map a Component list? 如何在NHibernate hbm xml(或在fluent-nhibernate类映射中)映射也是主键的组件? - How do you map a component that is also a primary key in NHibernate hbm xml (or in a fluent-nhibernate class map)? 如何告诉Fluent NHibernate不要映射类属性 - How to tell Fluent NHibernate not to map a class property 如何在Fluent NHibernate中将属性映射到多个属性? - How to map property to first of many in Fluent NHibernate? 流利的NHibernate:如何将db整数映射到datetime列? - Fluent NHibernate: How to map a db integer to a datetime column? 如何使用nHibernate Fluent映射来映射HasOne关系并避免N + 1? - How do you map a HasOne relationship with nHibernate Fluent mapping and avoid N+1? 流畅的nhibernate:如何使用属性为接口的属性映射实体? - Fluent nhibernate: How do I map an entity with a property who's type is an interface? 如何使用Fluent NHibernate将复合ID映射到复合用户类型? - How do you map a composite id to a composite user type with Fluent NHibernate?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM