2011-04-01 47 views
2

我有兩個實體,客戶和帳戶。客戶擁有多個帳戶。NHibernate - 非法訪問加載集合

我對客戶的映射是:

<bag cascade="all" name="Accounts" table ="Accounts" mutable="true" inverse="true"> 
    <key> 
    <column name="Customer_Id" /> 
    </key> 
    <one-to-many class="Account, POCOEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
</bag> 

我的帳號映射:

<many-to-one cascade="all" class="Customer, POCOEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer"> 
    <column name="Customer_Id" /> 
</many-to-one> 

在我的申請,我檢索客戶根據自己的ID:

var customer = _customerRepository.GetById(custID); 

然後我嘗試讓客戶的第一個帳戶:

Account account = customer.Accounts.FirstOrDefault(); 

然後我收到以下異常:「NHibernate.LazyInitializationException:非法獲取裝填回收」

我試過其他的方案來解決這個問題張貼在這裏,但沒有什麼工作。請告訴我非常奇怪的是,如果我插入下面的代碼之前我嘗試訪問該帳戶,然後一切正常:

var acc = from a in _accountRepository.GetAll() 
        where a.Customer.Equals(customer) 
        select a; 

所有我已經在前面的代碼做的是創造,我甚至不使用的變量。不知何故,它會導致聲明「帳戶帳戶= customer.Accounts.FirstOrDefault();」儘管如此。

任何人有任何想法這裏發生了什麼?

+0

您是否嘗試刪除「可變」屬性? – mathieu 2011-04-01 12:11:33

回答

4

我認爲這很簡單:你不再有一個開放的ISession與實體關聯。而且,我認爲這是因爲將會話管理(打開/關閉會話)作爲對存儲庫的響應而留下的,這是錯誤的。

+0

打開和關閉會話由單獨的工作單元處理。然後將相同的工作單位傳遞給所有存儲庫,以使它們與同一工作單元相關聯。我不把這個責任留給倉庫本身。 – JMc 2011-04-01 11:52:31

0

這裏的問題實際上是'ISession'被關閉了,雖然這不是因爲它正如前面建議的那樣由單個存儲庫處理。

問題的原因是我宣佈我的UnitOfWork(ISession)超出了我的業務方法範圍 - PlaceOrder()。例如:

ISession myUnitOfWork = new ISession(); 


public void PlaceOrder() 
{ 

    var myRepository = new IRepository<Customer>(myUnitOfWork); 
    .... 
    .... 
    Commit(); 
} 

所以到PlaceOrder()方法的第一個電話是好的,但額外調用的ISession已經關閉,因此該消息「非法裝載收集訪問」。解決的辦法是在PlaceOrder()方法內聲明的Isession:

public void PlaceOrder() 
{ 
    ISession myUnitOfWork = new ISession(); 
    var myRepository = new IRepository<Customer>(myUnitOfWork); 
    ....     

最終這個問題是缺乏的工作單元的概念的理解的結果。如果我的理解現在是正確的,那麼每個業務方法(如上面的PlaceOrder)都是一個新事務,因此需要在開始時打開ISession並在結束時關閉。我宣稱ISession不在該方法的範圍之內,認爲它只需要聲明一次。

+0

答案是2年前寫的,所以到目前爲止,你會擅長這個概念,但是ISession通常通過像Ninject或Castle Windsor這樣的IoC容器注入到存儲庫類的構造函數中,以利用UoW的好處。 IRepository也被注入到您的業務類的構造函數中,所以您不必在開始時打開ISession並在結束時關閉它。 – Andy 2013-11-08 16:08:49

0

我也遇到了這個錯誤 - 但我只在一箇中斷點注意到它。我的錯誤是由於DebuggerDisplay屬性試圖顯示正在被加載的屬性。

相關問題