Отображение коллекции строк с помощью NHibernate - PullRequest
13 голосов
/ 03 марта 2009

У меня есть класс домена со свойством IList<string>, которое я хочу сопоставить с таблицей с одним значением данных (т. Е. Он имеет идентификатор, идентификатор внешнего ключа для таблицы сущностей домена и столбец данных varchar) .

Я получаю сообщение об ошибке:

Ассоциация ссылается на несопоставленный класс: System.String

Как мне сопоставить таблицу с набором строк?

Ответы [ 3 ]

22 голосов
/ 04 марта 2009

Я просто столкнулся с подобной ситуацией; и я обнаружил, что действительно возможно отобразить коллекцию строк. Обратите внимание, что вам придется отображать эти строки как объекты-значения.

Вот что у меня есть:

public class Chapter
{
    private ISet<string> _synonyms = new HashedSet<string>();

    public ReadOnlyCollection<string> Synonyms
    {
       get { return new List<string>(_synonyms).AsReadOnly(); }
    }
}

Отображение:

<class name="Chapter" table="Chapter">
   <set name="Synonyms" table="ChapterSynonyms">
       <key column="ChapterId" />
       <element column="ChapterCode" type="string" />
   </set>
</class>
8 голосов
/ 11 мая 2009

Если я не ошибаюсь, вы можете сделать это:

<bag name="Identities" access="property">
  <key column="accountId"/>
  <element column="identity" type="string"/>
</bag>

Тождества, являющиеся IList<string>

1 голос
/ 03 марта 2009

Вы можете сделать это с IUserType следующим образом:

public class DelimitedList : IUserType
{
    private const string delimiter = "|";

    public new bool Equals(object x, object y)
    {
        return object.Equals(x, y);
    }

    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var r = rs[names[0]];
        return r == DBNull.Value 
            ? new List<string>()
            : ((string)r).SplitAndTrim(new [] { delimiter });
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        object paramVal = DBNull.Value;
        if (value != null)
        {
            paramVal = ((IEnumerable<string>)value).Join(delimiter);
        }
        var parameter = (IDataParameter)cmd.Parameters[index];
        parameter.Value = paramVal;
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public object Assemble(object cached, object owner)
    {
        return cached;
    }

    public object Disassemble(object value)
    {
        return value;
    }

    public SqlType[] SqlTypes
    {
        get { return new SqlType[] { new StringSqlType() }; }
    }

    public Type ReturnedType
    {
        get { return typeof(IList<string>); }
    }

    public bool IsMutable
    {
        get { return false; }
    }
}

Затем определите свойство IList как type = "MyApp.DelimitedList, MyApp".

ПРИМЕЧАНИЕ. SplitAndTrim - это расширение строки с различными переопределениями, которые я создал. Вот основной метод:

public static IList<string> SplitAndTrim(this string s, StringSplitOptions options, params string[] delimiters)
    {
        if (s == null)
        {
            return null;
        }
        var query = s.Split(delimiters, StringSplitOptions.None).Select(x => x.Trim());
        if (options == StringSplitOptions.RemoveEmptyEntries)
        {
            query = query.Where(x => x.Trim() != string.Empty);
        }
        return query.ToList();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...