如何将不区分大小写的字典映射到 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<TKey, TValue>
)。
【讨论】:
对不起,链接的样本是我能做的最好的。我不使用自定义集合类型。以上是关于如何将不区分大小写的字典映射到 NHibernate。?的主要内容,如果未能解决你的问题,请参考以下文章