Как сопоставить нечувствительный к регистру словарь в NHibernate.? - PullRequest
1 голос
/ 23 февраля 2010

Я создал нечувствительный к регистру словарь на C Sharp следующим образом. И следующий код вызывает исключение, так как в словаре регистр не учитывается.

IDictionary<string, ABCentre> names = new Dictionary<string, ABCentre>(StringComparer.OrdinalIgnoreCase);
        names.Add("LC001", new ABCentre());

        if (names.ContainsKey("lc001"))
        {
            names.Add("lc001", new ABCentre());// Exception , same key exists  
        }

Но при сопоставлении этого словаря (имен) с некоторым классом агрегации в NHibernate я не могу получить это исключение. то есть к клавишам может быть добавлен один и тот же текст с разными регистрами.

Имеет ли словарь имен замену тем, который NHibernate создает динамически (с использованием отражения), который чувствителен к регистру.

Может кто-нибудь подсказать, как сопоставить нечувствительный к регистру словарь с NHibernate .?

спасибо, Виджай

Ответы [ 2 ]

5 голосов
/ 20 апреля 2015

Прошло 5 лет, но, может быть, кто-то увидит это, поскольку не было четкого ответа.

Ответ Джейми об использовании CustomCollection является полностью правильным, это очень простой пример класса, отображения и IUserCollectionType, который должен помочь вам.

Большинство этих методов были украдены из фактического nhibernate-кода , за исключением Instantiate.

public class meta {
    public virtual Guid id { get; set; }
    public virtual IDictionary<string, string> data { get; set; }

    public meta() {
        data = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
    }
}

public class metamap : ClassMap<meta> {
    public metamap() {
        Table("metatable");
        Id(x=>x.id);
        HasMany(x => x.data)
            .Table("metadata")
            .AsMap<string>("skey")
            .Element("value")
            .CollectionType<DictionaryInsensitive<string>>()
            .Cascade.All()
            .KeyColumn("metaid");

    }
}

public class DictionaryInsensitive<T> :  IUserCollectionType {
    bool IUserCollectionType.Contains(object collection, object entity) {
        return ((IDictionary<string,T>) collection).Values.Contains((T)entity);
    }

    System.Collections.IEnumerable IUserCollectionType.GetElements(object collection) {
        return ((IDictionary<string,T>) collection).Values;
    }

    object IUserCollectionType.IndexOf(object collection, object entity) {
        var dictionary = (IDictionary<string, T>)collection;

        return dictionary
                .Where(pair => Equals(pair.Value, entity))
                .Select(pair => pair.Key)
                .FirstOrDefault();
    }

    object IUserCollectionType.Instantiate(int anticipatedSize) {
        return
            new Dictionary<string, T>(
                StringComparer.InvariantCultureIgnoreCase);
    }

    NHibernate.Collection.IPersistentCollection IUserCollectionType.Instantiate(NHibernate.Engine.ISessionImplementor session, NHibernate.Persister.Collection.ICollectionPersister persister) {
        return new PersistentGenericMap<string, T>(session);
    }

    object IUserCollectionType.ReplaceElements(object original, object target, NHibernate.Persister.Collection.ICollectionPersister cp, object owner, System.Collections.IDictionary copyCache, NHibernate.Engine.ISessionImplementor session) {
        IDictionary<string, T> result = (IDictionary<string, T>)target;
        result.Clear();

        IEnumerable<KeyValuePair<string, T>> iter = (IDictionary<string, T>)original;
        foreach (KeyValuePair<string, T> me in iter) {
            string key = (string)cp.IndexType.Replace(me.Key, null, session, owner, copyCache);
            T value = (T)cp.ElementType.Replace(me.Value, null, session, owner, copyCache);
            result[key] = value;
        }

        var originalPc = original as IPersistentCollection;
        var resultPc = result as IPersistentCollection;
        if (originalPc != null && resultPc != null) {
            if (!originalPc.IsDirty)
                resultPc.ClearDirty();
        }

        return result;
    }

    NHibernate.Collection.IPersistentCollection IUserCollectionType.Wrap(NHibernate.Engine.ISessionImplementor session, object collection) {
        var dict = new Dictionary<string, T>();
        return new PersistentGenericMap<string, T>(session, (IDictionary<string,T>)collection);
    }
}
2 голосов
/ 23 февраля 2010

Вам нужно будет создать и сопоставить пользовательскую коллекцию , чтобы NHIbernate мог использовать тип вашей коллекции. NHibernate имеет собственную реализацию IDictionary, которую он использует для коллекций, отображаемых как карта (NHibernate.Collection.PersistentGenericMap<TKey, TValue>).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...