7

ユーザー設定を名前と値のペアのコレクションに永続化しようとしています。値は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 <string、string>を次のようにマップします。

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

しかし、「オブジェクト」のタイプでは、NHibernateはそれを処理する方法を知りません。'オブジェクト'をそのタイプを表す文字列と値を表す文字列に分解するカスタムUserTypeを作成できると思います。次のようなテーブルがあります。

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> 

FluentNHibernateでこれをどのようにマッピングするかわかりません。

これを行うためのより良い方法があるかもしれません。あるいは、それを吸い上げてIDictionary <string、string>を使用する必要があるかもしれません。何か案は?

4

1 に答える 1

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
        };
        }
    }
}
于 2011-05-24T15:16:00.853 に答える