2012-07-05 20 views
0

我有ObjectDataSource的一個選擇方法:ObjectDataSource控件無法綁定列表時,NHibernate的代理對象,如果在第一位置

public static IEnumerable<Model.Domain.Theme> Select() 
    { 
     var cycleRepo = new RbaCycleRepository(Global.sessionFactory.GetCurrentSession()); 
     RbaCycle lacOpenCycle = cycleRepo.FindLacOpenCycle(); 
     if (lacOpenCycle != null) 
     { 
      var themeRepo = new ThemeRepository(Global.sessionFactory.GetCurrentSession()); 
      var result = themeRepo.FindAll(new ThemesForCycle(lacOpenCycle).GetQuery()); 
      return result; 
     } 
     return Enumerable.Empty<Model.Domain.Theme>(); 
    } 

這裏是情景:

  • 我按一下按鈕,一些操作被執行,因此我最終得到了一級代理主題第一級緩存中的對象 - 這很好。
  • 選擇()方法被調用並返回結果。結果只能包含主題對象或主題的混合NHibernate城堡代理(例如)。這是從監視窗口跡:

{} Castle.Proxies.ThemeProxy Model.Domain.Theme {Castle.Proxies.ThemeProxy} {} Model.Domain.Theme Model.Domain.Theme

  • 如果結果集合中的第一個對象是實際主題對象,那麼整個集合succeedes的結合。 但是,如果在收集第一個元素是代理對象,然後我結束了異常:

未處理的異常:System.Web.HttpUnhandledException: 類型「System.Web.HttpUnhandledException」引發的異常。 ---> System.Reflection.TargetInvocationException:屬性訪問器'標題' 對象'CIPNet.Model.Domain.Theme'拋出以下內容 異常:'對象與目標類型不匹配'。 ---> System.Reflection.TargetException:對象與目標類型不匹配。

編輯:這是執行的FindAll:

public IList<T> FindAll(QueryOver<T, T> query) 
    { 
     return query.GetExecutableQueryOver(session).List(); 
    } 

回答

0

這是我想出的臨時解決方案。它的工作原理,我只是確保綁定到控制列表有第一個對象,不是代理:

public static IList<T> ToProxySafeList<T>(this IList<T> list) 
     where T: class 
    { 
     if (list.Count == 0) return list; 

     var proxy = list[0] as INHibernateProxy; 
     if (proxy != null) 
     { 
      list[0] = proxy.HibernateLazyInitializer.GetImplementation() as T; 
     } 
     return list; 
    } 

有什麼建議嗎?

0

看起來像ObjectDataSource使用集合的第一個元件找出用於數據源的列。由於它使用反射,因此NHibernate/Castle DynamicProxy沒有機會取消對象。您可能需要手動執行此操作。

Identifying NHibernate proxy classes
NHibernate: Get concrete type of referenced abstract entity

另外,如果您的FindAll方法返回IQueriableIEnumerable,嘗試調用.ToList().ToArray()的結果,強制查詢執行。您可能不需要手動取消代理:

var result = 
    themeRepo.FindAll(new ThemesForCycle(lacOpenCycle).GetQuery()).ToList(); 
+0

謝謝,我已經打電話給ToList – dragonfly 2012-07-05 09:33:36

相關問題