2012-01-12 56 views
1

我有一些舊代碼正在執行查詢,其中模型可能是瞬態的。也就是說,從用戶輸入中填充了一些字段的模型,然後將其用作查詢的一部分。它在NH 2.1.x下工作,但在最新版本下失敗。通過瞬態實例NHibernate查詢導致「保存瞬態實例」-exception

引發的異常是「對象引用未保存的瞬態實例 - 在沖洗前保存瞬態實例」。當NH嘗試使用非持久對象作爲查詢的一部分執行查詢時,會發生這種情況。

簡化版本來說明問題。

​​

,並調用代碼是相同的:

Engine obj = new Engine { Id = 42 }; // Transient instance 
    var x = GetByEngine(obj); 

我希望發生(這似乎是老NHibernate的版本的行爲),是通過發動機只用於獲得Id。也就是說,生成SQl類似於 select ... from汽車引擎= 42

但是在新版本中,NHibernate似乎檢查在Expression中使用的引擎實際上是否持久。

有沒有辦法避免在執行查詢之前加載持久引擎?

回答

2

是使用Session.Load()它返回對象(如果已經在會話中)或lazyLoadingProxy(如果不存在)。

public static IList<Car> GetByEngine(Engine eng) { 
    ICriteria c = Session.CreateCriteria<Car>(); 
    c.Add(Expression.Eq("Engine", Session.Load<Engine>(eng.Id))); 
    return c.List<Car>(); 
} 
+0

對不起,延遲迴復。這會做到這一點,並在OP中回答我的問題。它解決了手頭的問題。 – Thomas 2012-01-31 08:47:02

1

您可以使用Session.Load方法,該方法存在於這種情況下。
0123'方法將返回一個Proxy給實體,並且不會訪問數據庫,直到您訪問其中一個屬性(除Primary key屬性根本不會觸及數據庫)。

用法:

Engine obj = session.Load<Engine>(42); 
var x = GetByEngine(obj); 

檢查this文章關於Session.GetSession.Load

0

我想你可以做這樣的事情:

public static IList<Car> GetByEngine(Engine eng) { 
    ICriteria c = Session.CreateCriteria<Car>().CreateCriteria("Engine"); 
    c.Add(Expression.Eq("Id", eng.Id)); 
    return c.List<Car>(); 
} 

反正......這怎麼可能是一輛車如果你還沒有保存,該引擎是否存在?

+0

這個例子很有意思,因爲實際的應用程序太複雜,無法在這裏發佈。這是再現行爲的最小情景。 – Thomas 2012-01-31 08:46:04

相關問題