2013-10-03 20 views
2

我們正在重構一個項目,從簡單的MySQL查詢到NHibernate的使用。 在MySQL連接器中有ExecuteNonQuery函數返回受影響的行。所以如何知道使用Session.Delete(查詢)刪除了多少個持久對象;

int RowsDeleted = ExecuteNonQuery("DELETE FROM `table` WHERE ..."); 

會告訴我有多少行被有效刪除。

我該如何實現與NHibernate一樣?到目前爲止,我可以看到這是不可能與Session.Delete(query);

我目前的解決方法是首先加載所有即將被刪除的對象,並逐個刪除它們,每次刪除時增加一個計數器。但是這可能會降低我可能承擔的性能。

回答

2

如果您不介意nHibernate會爲每行創建刪除語句,並且可能爲孤兒和/或其他關係創建附加語句,則可以使用session.Delete

爲了獲得更好的性能,我建議進行批量刪除(請參閱下面的示例)。

使用Session.delete

如果您刪除與執行Session.delete許多對象,NHibernate的確保了完整性被保留,如果需要的話,反正它都將加載到會話。因此,沒有真正的理由來計算您的對象或有一種方法來檢索已刪除的對象的數量,因爲您只需在運行刪除之前執行查詢以確定將受到影響的對象的數量...

以下語句將按ID刪除所有類型的實體。 select語句將查詢只爲ID,以便它實際上是非常高性能的數據庫...

var idList = session.Query<Post>().Select(p => p.Id).ToList<int>(); 
session.Delete(string.Format("from Post where Id in ({0})", string.Join(",", idList.ToArray()))); 

刪除將等於IDS在列表中的號碼的對象數...

這實際上是相同的(在查詢中的nHibernate將觸發對數據庫而言),如果你願意query<T>和遍歷結果並刪除所有的人一個接一個的......

批量刪除

你可以使用session.CreateSqlQuery來運行本機SQL命令。它也允許你有輸入和輸出參數。

下面的語句只會刪除一切從表中你所期望的

session.CreateSQLQuery(@"Delete from MyTableName"); 

要檢索的行數刪除,我們將使用正常TSQL @@ROWCOUNT變量,並通過選擇輸出。要檢索選定的行數,我們必須通過AddScalarUniqueResult簡單的返回到輸出參數添加到創建的查詢整數:

var rowsAffected = session.CreateSQLQuery(@" 
     Delete from MyTableName; 
     Select @@ROWCOUNT as NumberOfRows") 
    .AddScalar("NumberOfRows", NHibernateUtil.Int32) 
    .UniqueResult(); 

要傳遞的輸入變量,你可以做到這一點與.SetParameter(<name>,<value>)

var rowsAffected = session.CreateSQLQuery(@" 
     DELETE from MyTableName where ColumnName = :val; 
     select @@ROWCOUNT NumberOfRows;") 
    .AddScalar("NumberOfRows", NHibernateUtil.Int32) 
    .SetParameter("val", 1) 
    .UniqueResult(); 

我不太喜歡MySQL,我寫的例子是用於MSSQL的,我認爲在MySQL中@@ROWCOUNT的等價物應該是SELECT ROW_COUNT();

+0

謝謝你最有用的答案。但是,它會依賴應用程序數據庫類型,或者應該爲NHibernate支持的每種數據庫類型編寫查詢,並檢查在運行時使用哪種方言。我希望能有更優雅的方式。不過,你的答案是有價值的。 –

+0

實際上,沒有其他方法可以一次完成刪除操作(除了使用普通的sql對象並完全忽略nHibernate)。 如果使用正常的session.Delete或刪除多個實體,nHibernate將始終檢索關係並可能會刪除孤兒或交叉表條目。這很酷,但它會一直這樣做... NHibernate根本不是爲了做批量操作... – MichaC

+0

@MikedeKlerk我已經更新了我的答案的開始與另一個例子和一些解釋你爲什麼不如果您使用session.Delete,則不需要任何計數器... – MichaC

相關問題