2010-02-23 87 views
1

我已经在C Sharp中创建了一个不区分大小写的字典,如下所示。下面的代码会引发异常,因为字典不区分大小写。如何映射不区分大小写的字典到NHibernate。

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

你必须创建和映射custom collection使NHibernate的使用您的收藏类型。 NHibernate有自己的IDictionary实现,它用于映射为映射的集合(NHibernate.Collection.PersistentGenericMap<TKey, TValue>)。

+0

谢谢杰米,你可以发布一个示例代码。 – vijaysylvester 2010-03-12 04:56:20

+0

对不起,但链接的样本是我能做的最好的。我不使用自定义集合类型。 – 2010-03-12 13:30:43

4

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

杰米关于使用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); 
    } 
}