如何将不区分大小写的字典映射到 NHibernate。?

Posted

技术标签:

【中文标题】如何将不区分大小写的字典映射到 NHibernate。?【英文标题】:How to map a case insensitive dictionary to NHibernate.? 【发布时间】:2010-02-23 14:51:31 【问题描述】:

我在 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 动态创建(使用反射)的字典覆盖,它区分大小写。

有人可以建议,

谢谢, 维杰

【问题讨论】:

【参考方案1】:

这是 5 年后,但也许有人会看到这个,因为没有可靠的答案。

Jamie 关于使用 CustomCollection 的回答是完全正确的,这是一个非常简单的类、映射和 IUserCollectionType 示例,应该可以帮助您进行操作。

这些方法中的大多数都是从实际的nhibernate code 中窃取的,除了 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】:

您必须创建和映射custom collection 以使 NHIbernate 能够使用您的集合类型。 NHibernate 有自己的 IDictionary 实现,它用于将集合映射为映射 (NHibernate.Collection.PersistentGenericMap&lt;TKey, TValue&gt;)。

【讨论】:

对不起,链接的样本是我能做的最好的。我不使用自定义集合类型。

以上是关于如何将不区分大小写的字典映射到 NHibernate。?的主要内容,如果未能解决你的问题,请参考以下文章

如何让hibernate映射时字段区分大小写

使用不区分大小写的搜索过滤字典

字符串的字典比较[不区分大小写]

如何注释DTO以启用不区分大小写的映射?

hibernate 在表名映射时如何保持大小写区分呢?

映射不区分大小写 - 代码优先 - 实体框架