Domanda

ho a che fare con un database legacy che ha campi data e ora come char (8) colonne (in formato aaaammgg e hh: mm: ss, rispettivamente) in alcune delle tabelle. Come posso mappare le 2 colonne char a una singola proprietà .NET DateTime? Ho provato quanto segue, ma ottengo un errore "non può accedere setter", naturalmente, perché DateTime Data e timeofday proprietà sono di sola lettura:

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

Inoltre ho provato definente un'IUserType per DateTime, ma non posso capire. Ho fatto un sacco di googling per una risposta, ma non riesco a capire ancora. Qual è la mia migliore opzione per gestire questo stupido convention database legacy? Un esempio di codice sarebbe utile dal momento che non c'è molto fuori per la documentazione su alcuni di questi scenari più oscuri.

È stato utile?

Soluzione

Hai bisogno di un'ICompositeUserType di gestire più di una colonna. Hai bisogno di rinforzare il controllo degli errori, analisi formati, ecc, ma qui è un punto di partenza per voi.

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

}

=== mappatura fluente (supponendo automapping w / classi di override) ====

 public void Override(AutoMapping<MyClass> m)
 {
     ....
     m.Map(x => x.MyDateTime).CustomType<LegacyDateUserType>();
 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top