我在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。?
谢谢, vijay答案 0 :(得分:4)
这是5年之后,但也许有人会看到这个,因为没有可靠的答案。
Jamie关于使用CustomCollection的答案是完全正确的,这是一个非常简单的类,一个映射和一个IUserCollectionType的例子,可以帮助你。
除了Instantiate之外,大多数这些方法都是从实际的nhibernate code中窃取的。
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);
}
}
答案 1 :(得分:2)
您必须创建并映射custom collection以使NHIbernate能够使用您的集合类型。 NHibernate有自己的IDictionary实现,它用于映射为map(NHibernate.Collection.PersistentGenericMap<TKey, TValue>
)的集合。