2013-08-02 75 views
0

我使用的BindingSource以填補NHibernate的列表形式:NHibernate的袋的BindingSource

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類,或者如何解決綁定源的問題?

回答

0

這是因爲BindingSource無法發現列表類型: NHibernate的持久包沒有ITypedList接口,也沒有Indexer Property public。 在添加映射之前,您需要用自定義替換NHibernate CollectionTypeFactory。 我附上我的實現:

PersistentGenericBag:

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>();