0

Create (INSERT) 動作を SELECT 動作から分離する方法はありますか。

このような文字列を返す列を持つデータベースがあるとしましょう

Predecessors = "1,3,4,5"

私のアプリケーションでは、IUserType を実装して、この文字列を int 配列のように使用したいと考えています。

public interface IIntArray
{
    int[] Items { get; set; }
}

public class IntArray : IIntArray
{
    public int[] Items { get; set; }

    public IntArray(string item)
    {
        if(string.IsNullOrEmpty(item))
            return;

        Items = System.Array.ConvertAll<string, int>(item.Split(new[] {','}), int.Parse);

        // for older .net versions use the code below
        // Items = Array.ConvertAll<string, int>(item.ToString().Split(new[] { ',' }), delegate(string str) { return int.Parse(str); });
    }
}

public class IntArrayType : IUserType
{
    #region Implementation of IUserType

    /// <summary>
    /// Compare two instances of the class mapped by this type for persistent "equality"
    /// ie. equality of persistent state
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public new bool Equals(object x, object y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        return x.GetType() == y.GetType();
    }

    /// <summary>
    /// Get a hashcode for the instance, consistent with persistence "equality"
    /// </summary>
    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    /// <summary>
    /// Retrieve an instance of the mapped class from a resultset.
    /// Implementors should handle possibility of null values.
    /// </summary>
    /// <param name="rs">a IDataReader</param>
    /// <param name="names">column names</param>
    /// <param name="owner">the containing entity</param>
    /// <returns></returns>
    /// <exception cref="HibernateException">HibernateException</exception>
    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var value = NHibernateUtil.String.NullSafeGet(rs, names[0]);

        if (value == null || (string.IsNullOrEmpty(value.ToString())))
        {
            return null;
        }

        return new IntArray(value.ToString());
    }

    /// <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>
    /// <param name="cmd">a IDbCommand</param>
    /// <param name="value">the object to write</param>
    /// <param name="index">command parameter index</param>
    /// <exception cref="HibernateException">HibernateException</exception>
    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        if (value == null)
        {
            ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
        }
        else
        {
            var state = (IIntArray)value;
            ((IDataParameter)cmd.Parameters[index]).Value = state.GetType().Name;
        }
    }

    /// <summary>
    /// Return a deep copy of the persistent state, stopping at entities and at collections.
    /// </summary>
    /// <param name="value">generally a collection element or entity field</param>
    /// <returns>a copy</returns>
    public object DeepCopy(object value)
    {
        return value;
    }

    /// <summary>
    /// During merge, replace the existing (<paramref name="target" />) value in the entity
    /// we are merging to with a new (<paramref name="original" />) value from the detached
    /// entity we are merging. For immutable objects, or null values, it is safe to simply
    /// return the first parameter. For mutable objects, it is safe to return a copy of the
    /// first parameter. For objects with component values, it might make sense to
    /// recursively replace component values.
    /// </summary>
    /// <param name="original">the value from the detached entity being merged</param>
    /// <param name="target">the value in the managed entity</param>
    /// <param name="owner">the managed entity</param>
    /// <returns>the value to be merged</returns>
    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    /// <summary>
    /// Reconstruct an object from the cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. (optional operation)
    /// </summary>
    /// <param name="cached">the object to be cached</param>
    /// <param name="owner">the owner of the cached object</param>
    /// <returns>a reconstructed object from the cachable representation</returns>
    public object Assemble(object cached, object owner)
    {
        return cached;
    }

    /// <summary>
    /// Transform the object into its cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. That may not be enough
    /// for some implementations, however; for example, associations must be cached as
    /// identifier values. (optional operation)
    /// </summary>
    /// <param name="value">the object to be cached</param>
    /// <returns>a cacheable representation of the object</returns>
    public object Disassemble(object value)
    {
        return value;
    }

    /// <summary>
    /// The SQL types for the columns mapped by this type. 
    /// </summary>
    public SqlType[] SqlTypes { get { return new[] { NHibernateUtil.String.SqlType }; } }

    /// <summary>
    /// The type returned by <c>NullSafeGet()</c>
    /// </summary>
    public Type ReturnedType { get { return typeof(IntArray); } }

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

    #endregion
}

私のNHibernateクラスでは、このようにプロパティにマッピングしました

public virtual IntArray Predecessors { get; set; }

そして hbm マッピング

<property name="Predecessors" type="Example.IntArrayType, Example" />

IntArray クラスは、データを読み取るときにその仕事をしますが、何かを元に戻そうとすると、これは機能しません。私がやりたいことは、IntArray プロパティに IntArray.Items の値をカンマ区切りの文字列にレンダリングさせることです。

string magic = string.Join(",", Predecessors.Items);

ありがとう

4

1 に答える 1

0

このような何かがトリックを行う必要があります

public void NullSafeSet(IDbCommand cmd, object value, int index)
{
    var ints = value as IntArray;
    if(ints != null && ints.Items != null)
    {
      NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, string.Join(", ", ints.Items), index);
    }
}
于 2013-02-04T06:14:53.753 に答える