带装订源的冬眠包
本文关键字:冬眠 | 更新日期: 2023-09-27 18:25:57
我正在使用绑定源来填写Nhibernate列表中的表单:
public class Customer{
public string Name { get; set;}
public IList<Order> Orders { get; set;}
}
bindingSourceCustomer.DataSource = session.Query<Customer>().ToList();
bindingSourceOrder.DataSource = bindingSourceCustomer;
bindingSourceOrder.DataMember = "Orders";
现在我打
bindingSourceOrder.AddNew();
抛出一个异常:
值"System.Object"的类型不是"Model.Order",不能此泛型集合中使用的。
现在我把第一行改成:
bindingSourceCustomer.DataSource = session.Query<Customer>().Select(customer =>
{
customer.Orders = customer.Orders.ToList();
return customer;
})
.ToList();
它之所以有效,是因为Nhibernate使用PersistentBag作为IList的实现,这显然不能很好地与绑定源一起工作(据我所见)。
关于如何让Nhibernate返回List类,或者如何解决绑定源的问题,有什么建议吗?
这是因为BindingSource无法发现列表类型:NHibernate的持久包既没有ITypedList接口,也没有Indexer属性public。在添加映射之前,您需要将NHibernate CollectionTypeFactory替换为自定义的。我附上我的实现:
持久通用包:
public class EnhancedPersistentGenericBag<T> : PersistentGenericBag<T> , ITypedList
{
public EnhancedPersistentGenericBag(ISessionImplementor session, ICollection<T> coll) : base(session, coll) { }
public EnhancedPersistentGenericBag(ISessionImplementor session) : base(session) { }
public EnhancedPersistentGenericBag() { }
public new T this[int index]
{
get
{
return (T)base[index];
}
set
{
base[index] = value;
}
}
public string GetListName(PropertyDescriptor[] listAccessors) { return GetType().Name; }
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
return TypeDescriptor.GetProperties(typeof(T));
}
}
CollectionTypeFactory:
public class EnhancedCollectionTypeFactory : DefaultCollectionTypeFactory
{
public override CollectionType Bag<T>(string role, string propertyRef, bool embedded)
{
return new EnhancedGenericBagType<T>(role, propertyRef);
}
}
GenericBagType:
public class EnhancedGenericBagType<T> : BagType
{
public EnhancedGenericBagType(string role, string propertyRef) :
base(role, propertyRef, false) { }
public override IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister, object key)
{
return new EnhancedPersistentGenericBag<T>(session);
}
public override IPersistentCollection Wrap(ISessionImplementor session, object collection)
{
return new EnhancedPersistentGenericBag<T>(session, (ICollection<T>)collection);
}
public override Type ReturnedClass
{
get
{
return typeof(ICollection<T>);
}
}
protected override void Add(object collection, object element)
{
((ICollection<T>)collection).Add((T)element);
}
protected override void Clear(object collection)
{
((ICollection<T>)collection).Clear();
}
public override object Instantiate(int anticipatedSize)
{
if (anticipatedSize > 0)
return new List<T>(anticipatedSize + 1);
else
return new List<T>();
}
}
如何覆盖默认CollectionTypeFactory:
Configuration cfg = new Configuration();
cfg.CollectionTypeFactory<EnhancedCollectionTypeFactory>();