2014-01-09 44 views
2

我有一個存儲過程使用這個腳本在SQL工作室管理快速測試時返回2個記錄:NHibernate的GetNamedQuery執行存儲過程,但返回空列表

declare @route_id_param as varchar(10), @start_time as datetime, @start_date as datetime, @end_date as datetime 
set @start_time = GETDATE() 
set @start_date = CONVERT(DATETIME,'10/26/2013',101) 
set @end_date = CONVERT(DATETIME,'12/26/2020',101)  

exec dbo.sp_get_deactivation_list @companyId=1, @startDate = @start_date, @endDate = @end_date; 
select execution_time_in_ms = DATEDIFF(millisecond, @start_time, getdate()) 
GO 

當我試圖從NHibernate的執行同一個存儲過程,使用下面的映射文件,我得到0結果。

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping 
    xmlns="urn:nhibernate-mapping-2.2" 
    assembly="HGT.IridiumAirtime.Service" 
    namespace="HGT.IridiumAirtime.Service.Model"> 
    <sql-query name="GetDeactivationList" callable="true"> 
    <query-param name="companyId" type="int"/> 
    <query-param name="startDate" type="DateTime"/> 
    <query-param name="endDate" type="DateTime"/> 
    <!--<return class="Activation"> 
     <return-property column="MobileId" name="MobileId" /> 
     <return-property column="RadioAddress" name="RadioAddress" /> 
     <return-property column="DeactivationDate" name="DeactivationDate" /> 
    </return>--> 
    exec [sp_get_deactivation_list] @companyId=:companyId, @startDate=:startDate, @endDate=:endDate 
    </sql-query> 

</hibernate-mapping> 

是執行所說的存儲過程的方法是:

public IEnumerable<TOut> ExecuteStoredProcedure<TOut>(string procedureName, IList<SqlParameter> parameters) 
    { 
     IEnumerable<TOut> result; 

     using (var session = _sessionFactory.OpenSession()) 
     { 
      var query = session.GetNamedQuery(procedureName); 
      foreach (var parameter in parameters) 
      { 
       query.SetParameter(parameter.ParameterName, parameter.Value); 
      } 
      AddStoredProcedureParameters(query, parameters); 
      result = query.List<TOut>(); 
     } 

     return result; 
    } 

我甚至產生了這種激活類型的新映射文件,即使沒有相關的表,但NHibernate的不返回正確的結果。在過程的映射文件中取消註釋類型映射定義不會改變結果。我在這裏錯過了什麼嗎?

我沒有得到任何例外,所以它看起來像程序正在執行。

UPDATE:1刪除呼叫AddStoredProcedureParameters並用的方法體代替。

更新2添加存儲過程:

if OBJECT_ID ('dbo.[sp_get_deactivation_list]', 'P') is not null 
    drop procedure dbo.[sp_get_deactivation_list]; 
go 

create procedure [dbo].[sp_get_deactivation_list] 
    @companyId int, 
    @startDate DateTime, 
    @endDate DateTime 
as 
begin  
    select 
     assMobileRadio.Mobile_ID as MobileId, 
     tblRadioinfo.Radio_Address as RadioAddress, 
     tblRadioinfo.Deactivation_Date as DeactivationDate 
    from tblRadioinfo 
    left join assMobileRadio 
    on tblRadioinfo.Radio_ID = assMobileRadio.Radio_ID 
    where tblRadioinfo.Radio_Type_ID in (2, 4, 7) 
    and tblRadioinfo.Company_ID = @companyId 
    and tblRadioinfo.Deactivation_Date <= @endDate 
    and tblRadioinfo.Deactivation_Date >= @startDate 
    and tblRadioinfo.Radio_Address in (select IMEI from [airtime_cdrs] where Effective_Date > @startDate and Effective_Date < @endDate) 
from airtimes_cte for xml path('')),1,1,''))  
    ORDER BY tblRadioinfo.Deactivation_Date 
end 

回答

3

我剛剛試過你的映射(儘可能相同)和你的1)映射和2)調用是OK的。除了事實,我不知道該呼叫的AddStoredProcedureParameters

所以裏面,這是工作:

var query = session.GetNamedQuery("GetDeactivationList"); 
    query.SetParameter("companyId", 1); 
    query.SetParameter("startDate", new DateTime(2013,10,26)); 
    query.SetParameter("endDate", new DateTime(2020,12,26)); 

// if the <return class="Activation"> is commented ... we'll get object[] 
var list = query.List<object[]>(); 

,這是工作。也就是說。你的映射正在工作。 SQL調用(exec sp)被觸發,因爲如果找不到指定的查詢,或者會發生其他問題,我們將得到一個Exception

唯一正確的現在懷疑是黑匣子AddStoredProcedureParameters(不能將其切換的開始和結束日期?)

我會建議,檢查你的SQL Server事件探查器中的單元測試,你會看到什麼傳遞給數據庫...你可以採取並重新執行。

+0

+1,用於參考SQL事件探查器。由於我在Express上,我使用了https://expressprofiler.codeplex.com/中的ExpressProfiler,它確認正在執行以下操作:exec sp_executesql N'exec [sp_get_deactivation_list] @ companyId = @ p0,@ startDate = @ p1, @ endDate = @ p2',N'@ p0 int,@ p1 datetime,@ p2 datetime',@ p0 = 1,@ p1 ='2013-10-26 00:00:00',@ p2 ='2020-12 -16 00:00:00' 去。仍然沒有輸出。你爲什麼要做query.List 而不是query.List ? –

+0

我有一個類似的存儲過程,名爲GetTransmissionSum通過NHibernate成功執行。當執行這一個時,Express Profiler給出31的CPU,3788的讀數和41ms的持續時間。但是,執行GetDeactivationList時,CPU爲0,讀取爲3,持續時間爲0ms。當我在Studio Management Express中對GetDeactivationList執行測試腳本時,CPU爲125,讀取時間爲3991,持續時間爲124ms。 –

+0

當我rexecute正在傳遞給數據庫的查詢,它返回0的計數。嗯。 –

0

如果激活非管理實體與NHibernate您可以使用此:

var query = session.GetNamedQuery(procedureName); 

AddStoredProcedureParameters(query, parameters); 

result = query.SetResultTransformer(Transformers.AliasToBean(typeof(TOut))) 
    .List<TOut>(); 

如果不嘗試添加alias

<return alias="activation" class="Activation"> 
    ... 
</return> 

例如:

<sql-query name="mySqlQuery"> 
    <return alias="person" class="eg.Person"> 
     <return-property name="Name" column="myName"/> 
     <return-property name="Age" column="myAge"/> 
     <return-property name="Sex" column="mySex"/> 
    </return> 
    SELECT person.NAME AS myName, 
      person.AGE AS myAge, 
      person.SEX AS mySex, 
    FROM PERSON person WHERE person.NAME LIKE :name 
</sql-query> 

參考here是解決您的問題的一些更多的方法。 只需要對nhibernate怎麼說返回數據,「這個」欄目「解決這個」屬性。

對不起,我英文很差。

+0

感謝您的回覆。 query.SetResultTransformer()。列表()是我在運行到相關文章之前的代碼。將再次嘗試,但我記得,這沒有奏效。你能否澄清第二段?我應該取消註釋激活映射並添加別名? –

2

如果執行你的存儲過程(不完全使用GetNamedQuery)你的主要目的,你可以使用以下命令:

假設你的方法參數是:INT? ID,日期時間? FromDate,DateTime? TODATE(所有空的值)

IList<TOut> result = session.CreateSQLQuery("exec [dbo].[sp_get_deactivation_list]:param1, :param2, :param3") 
    .SetParameter("param1", id, NHibernateUtil.Int32) 
    .SetParameter("param2", fromDate, NHibernateUtil.DateTime) 
    .SetParameter("param3", toDate, NHibernateUtil.DateTime) 
    .SetResultTransformer(Transformers.AliasToBean<TOut>()).List<TOut>(); 

return result; 

而且在上課吹捧你的映射文件,只是有相關屬性爲正常。

+0

謝謝,但還有其他問題與調用GetNamedQuery及其參數無關。 –