Как сопоставить IDictionary <string, object> в беглой NHibernate?

Я хочу сохранить пользовательские настройки в коллекции пар имя-значение, где значение может быть 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, хотя я думаю, что это возможно.

Как правило, вам нужно отобразить более простой словарь <string, string> как:

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 <string, string & gt ;. Есть идеи?

7 голосов | спросил Nick W 21 MaramSun, 21 Mar 2010 03:52:40 +03002010-03-21T03:52:40+03:0003 2010, 03:52:40

1 ответ


0

Я бы сказал, что 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
        };
        }
    }
}
ответил Firo 24 Maypm11 2011, 19:16:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132