【问题标题】:How to map IDictionary<string, object> in Fluent NHibernate?如何在 Fluent NHibernate 中映射 IDictionary<string, object>?
【发布时间】:2011-01-29 22:24:16
【问题描述】:

我希望将用户偏好保存到名称值对的集合中,其中值可能是 int、bool 或字符串。

有几种方法可以给这只猫剥皮,但我能想到的最方便的方法是这样的:

public class User
{
    public virtual IDictionary<string, object> Preferences { get; set; }
}

其用法为:

user.Preferences["preference1"] = "some value";
user.Preferences["preference2"] = 10;
user.Preferences["preference3"] = true;

var pref = (int)user.Preferences["preference2"];

我不确定如何在 Fluent NHibernate 中进行映射,但我认为这是可能的。

通常,您会将更简单的 Dictionary 映射为:

HasMany(x => x.Preferences)
    .Table("Preferences")
    .AsMap("preferenceName")
    .Element("preferenceValue");

但是对于“对象”类型,NHibernate 不知道如何处理它。我想可以创建一个自定义用户类型,将“对象”分解为一个表示其类型的字符串和一个表示值的字符串。我们会有一个看起来像这样的表:

Table Preferences
    userId (int)
    preferenceName (varchar)
    preferenceValue (varchar)
    preferenceValueType (varchar)

而休眠映射是这样的:

<map name="Preferences" table="Preferences"> 
  <key column="userId"></key> 
  <index column="preferenceName" type="String" />
  <element type="ObjectAsStringUserType, Assembly">
    <column name="preferenceValue" /> 
    <column name="preferenceValueType"/> 
  </element> 
</map> 

我不确定您将如何在 Fluent NHibernate 中映射它。

也许有更好的方法可以做到这一点,或者我应该接受它并使用 IDictionary。有什么想法吗?

【问题讨论】:

  • 谢谢,正是我要找的东西

标签: fluent-nhibernate dictionary mapping preferences usertype


【解决方案1】:

我会说IDictionary&lt;string,string&gt; 会容易得多。但是这里是代码

        HasMany(u => u.Preferences)
            .Table("Preferences")
            .AsMap("preferenceName")
            .Element("preferenceType", e => e.Column("preferenceValue").Type<ObjAsStringUserType>());

class ObjAsStringUserType : ImmutableUserType
{
    public override object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var type = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
        var value = (string)NHibernateUtil.String.NullSafeGet(rs, names[1]);

        switch (type)
        {
            case "boolean":
                return bool.Parse(value);
                ...
            default:
                return null;
                break;
        }
    }

    public override void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        var type = value.GetType().Name;
        var valuestring = value.ToString(CultureInfo.InvariantCulture);

        NHibernateUtil.String.NullSafeSet(cmd, type, index);
        NHibernateUtil.String.NullSafeSet(cmd, valuestring, index + 1);
    }

    public override Type ReturnedType
    {
        get { return typeof(object); }
    }

    public override SqlType[] SqlTypes
    {
        get { return new []
        {
            SqlTypeFactory.GetString(length: 255),  // preferenceType
            SqlTypeFactory.GetString(length: 255),  // preferenceValue
        };
        }
    }
}

【讨论】:

  • 感谢小伙子的帮助,发现了
  • 什么是 ImmutableUserType?我在 NHibernate 或 FNH 中找不到对它的引用。
  • @JeffDoolittle 这是我自己实现 NH 的 IUseryType 的基本类型。我把它贴在这里stackoverflow.com/a/7484139/671619
猜你喜欢
  • 2012-01-02
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2011-02-06
  • 2011-04-10
  • 2012-04-09
相关资源
最近更新 更多