我希望将用户首选项保存到名称值对的集合中,其中值可以是int,bool或string。
有几种方法可以为这只猫提供皮肤,但我能想到的最方便的方法是:
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&lt; string,string&gt;为:
HasMany(x => x.Preferences)
.Table("Preferences")
.AsMap("preferenceName")
.Element("preferenceValue");
但是对于一种'对象',NHibernate不知道如何处理它。我想可以创建一个自定义UserType,它将“对象”分解为表示其Type的字符串和表示该值的字符串。我们有一张看起来像这样的表:
Table Preferences
userId (int)
preferenceName (varchar)
preferenceValue (varchar)
preferenceValueType (varchar)
并且hibernate映射会这样:
<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&lt; string,string&gt;。有什么想法吗?
答案 0 :(得分:6)
我会说IDictionary<string,string>
会容易得多。不过这是代码
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
};
}
}
}