0

マップせずColorにColor属性を持つオブジェクトをマップすると、FluentNHibernate正常にマップされますvarbinary(max)。ただし、現実的Colorには4バイトで構成されていることを考えると、これは非常に非効率的であり、プロキシに新しいタイプを使用せずに改善することに熱心です。

内部Color的には4つのプロパティで構成されています。

  1. long valueint( ARGBを表すためにキャストダウン)
  2. short state、これが既知の有効な色であるかどうかを示します
  3. string name、わかっている場合は色の名前。
  4. short knownColor既知の色を示す値

そこで、これを次のようにマッピングしようとしました。

public ColorMapping()
{
    CompositeId()
        .KeyProperty(c => Reveal.Member<Color, long>("value"))
        .KeyProperty(c => Reveal.Member<Color, short>("state"))
        .KeyProperty(c => Reveal.Member<Color, string>("name"))
        .KeyProperty(c => Reveal.Member<Color, short>("knownColor"));
}

ただし、使用時に次の例外が発生します。

クラス初期化メソッドDataContextTest.ClassInitialiseが例外をスローしました。FluentNHibernate.Cfg.FluentConfigurationException:FluentNHibernate.Cfg.FluentConfigurationException:SessionFactoryの作成中に無効または不完全な構成が使用されました。詳細については、PotentialReasonsコレクションとInnerExceptionを確認してください。

---> FluentNHibernate.Cfg.FluentConfigurationException:SessionFactoryの作成中に、無効または不完全な構成が使用されました。詳細については、PotentialReasonsコレクションとInnerExceptionを確認してください。

---> NHibernate.MappingException:マッピングドキュメントをコンパイルできませんでした:(XmlDocument)---> NHibernate.MappingException:次のタイプを判別できませんでした:System.Linq.Expressions.Expression 1[[System.Func2 [[System.Drawing.Color、System。描画、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = b03f5f7f11d50a3a]、[System.Int64、mscorlib、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = b77a5c561934e089]]、mscorlib、Version = 4.0.0.0、Culture =ニュートラル、PublicKeyToken = b77a5c561934e089]]、System.Core、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = b77a5c561934e089、列の場合:NHibernate.Mapping.Column(Member)。

私は誤用していRevealますか?もしそうなら、私はそれをどのように使用するつもりですか?

4

2 に答える 2

1

私はそれを前後に変換するUserTypeとしてマップします

// in mapping
Map(x => x.Color).Column("ColorARGB").CustomType<ColorUserType>();

[Serializable]
class ColorUserType : IUserType
{
    public object Assemble(object cached, object owner)
    {
        return DeepCopy(cached);
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Disassemble(object value)
    {
        return DeepCopy(value);
    }

    bool IUserType.Equals(object x, object y)
    {
        var colorX = x as Color;
        var colorY = y as Color;
        return colorX == null ? colorY = null : colorX.ToArgb() == colorY.ToArgb();
    }

    public virtual int GetHashCode(object x)
    {
        var colorX = (Color)x;
        return (colorX != null) ? colorX.ToArgb() : 0;
    }

    public bool IsMutable { get { return false; } }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        return Color.FromArgb((int)NHibernateUtil.Int32.Get(rs, names[0]));
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        NHibernateUtil.Int32.Set(cmd, ((Color)value).ToArgb(), index);
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public Type ReturnedType { get { return typeof(Color); } }

    public SqlType[] SqlTypes { get { return new []{ SqlTypeFactory.Int32 }; } }
}
于 2012-10-05T10:23:04.233 に答える
0

最後にICompositeUserTypeを使用しました。次のようにコーディングします。

public class ColorType : ICompositeUserType
{
    /// <summary>
    /// Get the value of a property
    /// </summary>
    /// <param name="component">an instance of class mapped by this "type"</param>
    /// <param name="property"/>
    /// <returns>
    /// the property value
    /// </returns>
    public object GetPropertyValue(object component, int property)
    {
        var color = (Color) component;
        if (property == 0)
        {
            return color.ToArgb();
        }

        return (int) color.ToKnownColor();
    }

    /// <summary>
    /// Set the value of a property
    /// </summary>
    /// <param name="component">an instance of class mapped by this "type"</param>
    /// <param name="property"/>
    /// <param name="value">the value to set</param>
    public void SetPropertyValue(object component, int property, object value)
    {
        throw new InvalidOperationException("Color is immutable");
    }

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

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

    /// <summary>
    /// Retrieve an instance of the mapped class from a IDataReader. Implementors
    ///             should handle possibility of null values.
    /// </summary>
    /// <param name="dr">IDataReader</param>
    /// <param name="names">the column names</param>
    /// <param name="session"/>
    /// <param name="owner">the containing entity</param>
    /// <returns/>
    public object NullSafeGet(IDataReader dr, string[] names,
        ISessionImplementor session, object owner)
    {
        var argb = (int?) NHibernateUtil.Int32.NullSafeGet(dr, names[0]);
        var knownColor = (int?) NHibernateUtil.Int32.NullSafeGet(dr, names[1]);
        return knownColor != null
            ? Color.FromKnownColor((KnownColor) knownColor.Value)
            : Color.FromArgb(argb.Value);
    }

    /// <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.
    ///             If a property is not settable, skip it and don't increment the index.
    /// </summary>
    /// <param name="cmd"/>
    /// <param name="value"/>
    /// <param name="index"/>
    /// <param name="settable"/>
    /// <param name="session"/>
    public void NullSafeSet(IDbCommand cmd, object value, int index,
        bool[] settable, ISessionImplementor session)
    {
        var color = (Color) value;
        if (color.IsKnownColor)
        {
            ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
            ((IDataParameter) cmd.Parameters[index + 1]).Value = (int) color.ToKnownColor();
        }
        else
        {
            ((IDataParameter) cmd.Parameters[index]).Value = color.ToArgb();
            ((IDataParameter) cmd.Parameters[index + 1]).Value = DBNull.Value;
        }
    }

    /// <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/>
    public object DeepCopy(object value)
    {
        return value;
    }

    /// <summary>
    /// Transform the object into its cacheable representation.
    ///             At the very least this method should perform a deep copy.
    ///             That may not be enough for some implementations, 
    ///             method should perform a deep copy. 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>
    /// <param name="session"/>
    /// <returns/>
    public object Disassemble(object value, ISessionImplementor session)
    {
        return value;
    }

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

    /// <summary>
    /// During merge, replace the existing (target) value in the entity we are merging to
    ///             with a new (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. However, since
    ///             composite user types often define component values, it might make sense to recursively
    ///             replace component values in the target object.
    /// </summary>
    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[] {"Argb", "KnownColor"}; } }

    /// <summary>
    /// Get the corresponding "property types"
    /// </summary>
    public IType[] PropertyTypes
    {
        get
        {
            return new IType[]
                   {
                       NHibernateUtil.Int32, NHibernateUtil.Int32
                   };
        }
    }

    /// <summary>
    /// The class returned by NullSafeGet().
    /// </summary>
    public Type ReturnedClass { get { return typeof (Color); } }

    /// <summary>
    /// Are objects of this type mutable?
    /// </summary>
    public bool IsMutable { get { return false; } }
}
于 2012-10-28T22:29:16.547 に答える