2012-08-01 78 views
7

我有加載集合的問題。我有的設置是簡單的一對多關聯,使用FluentNHibernate進行映射。實體裝載withough被拋出的異常,但訪問相關集合顯示「非法獲取裝填回收」。我將在這裏粘貼相關部分的代碼。NHibernate的集合裝載,「非法獲取裝填回收」

[Serializable] 
[DataContract(IsReference = true)] 
public partial class Department : Entity 
{ 
    ... 
    [DataMember] 
    public virtual IList<PressJobRun> PressJobRun 
    { 
     get { return pressJobRunField; } 
     protected set { pressJobRunField = value; } 
    } 
    ... 
} 

映射如下

public DepartmentMap() 
{ 
    Id(x => x.Id); 
    Map(x => x.Name) 
     .Not.Nullable() 
     .Length(100); 
    HasMany(x => x.PressJobRun) 
     .AsBag() 
     .Inverse() 
     .Cascade.AllDeleteOrphan() 
     .LazyLoad() 
     .BatchSize(50); 
    ... 
} 

我也嘗試禁用延遲加載,通過排除行,並通過調用.Not.LazyLoad(),但最終是一樣的。

using (var tx = m_Repository.Session.BeginTransaction()) 
    { 
     var depts = m_Repository.Session.CreateCriteria<Department>().List<Department>(); 
     var dept = depts[0]; 
     ... 
    } 

我意識到暴露Session並不是要做的事情,但這是爲了確保會話是開放的。

當我鑽到例外,我看到下面的堆棧跟蹤:

at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) 
    at NHibernate.Collection.AbstractPersistentCollection.Read() 
    at NHibernate.Collection.AbstractPersistentCollection.ReadSize() 
    at NHibernate.Collection.PersistentBag.get_Count() 
    at NHibernate.DebugHelpers.CollectionProxy`1.get_Items() 

有趣的小鬼來這裏。我在PressJobRun屬性的setter行上設置了斷點。

  • 如果我跨過它,並快速監視pressJobRunField,我看到了「裝載例外非法訪問」。
  • ,如果我第一次快速的手錶value變量,我看到加載的集合。按預期順序執行setter行。

我用什麼

  • 的Visual Studio 2012,目標.NET 4
  • NHibernate的3.3.1.400
  • SQL CE 4
  • 城堡
  • 城堡AutoTx facitlity
  • 我管理會話p呃WCF要求自己

我已經試過

  • 禁用延遲加載
  • 確信會議是開放的,而且它是有問題的代碼執行期間同一會話
  • 切換Inverted地圖集合(以爲我相信它應該被反轉)
  • 清理和重建解決方案
  • Configuration Manager中確信,在溶液中的所有項目正在建設
  • 組調試器上的所有拋出的異常中斷。調試器不與我在收藏查看設置

回答

3

問題是,當PressJobRub.Department屬性設置,我的代碼還增加了PressJobRun適當收集Department異常中斷。我做了初始化集合,但問題是當調用Contains()方法時,由於某種原因NHibernate使用的集合失敗。我仍然懷疑我在問題中描述的gremlin,以及爲什麼調試器在未打開時沒有中斷異常'只啓用我的代碼調試'並將其設置爲打破拋出異常。

無論如何,解決方案是映射PressJobRun.Department訪問字段(在我的情況下爲Access.PascalCaseField(Prefix.mUnderscore)),以避免呼叫,將實體添加到Department.PressJobRun集合。

Krzysztof Kozmic's article解釋了這一點,雖然在我的情況下收集並不是未初始化的。