首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >映射System.Drawing.Color

映射System.Drawing.Color
EN

Stack Overflow用户
提问于 2012-10-01 19:59:02
回答 2查看 736关注 0票数 0

如果我不映射Color,而是映射具有颜色属性的对象,则FluentNHibernate成功地将其映射到varbinary(max)。但是,考虑到现实中的Color只由4个字节组成,这是非常低效的,我非常希望在不使用新类型代理的情况下对其进行改进。

Color内部,它由四个属性组成,

  1. long value (转换为int来表示ARGB)
  2. short state,指示这是否是已知的有效颜色。
  3. string name,颜色的名称,如果知道的话。
  4. short knownColor值表示它是哪种已知颜色

因此,我试图如下所示。

代码语言:javascript
复制
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.Mapping.Column(成员)。

我在滥用Reveal吗?如果是这样的话,我该如何使用它呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-05 10:23:04

我会把它映射成UserType,它来回转换

代码语言:javascript
复制
// 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 }; } }
}
票数 1
EN

Stack Overflow用户

发布于 2012-10-28 22:29:16

最后我用了一个ICompositeUserType。代码如下,

代码语言:javascript
复制
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; } }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12680163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档