2016-02-28 70 views
0

我想用NHibernate執行一個HQL查詢。當我嘗試執行查詢時,它會引發異常,我不明白是什麼問題。如何使用IList與HQL查詢和NHibernate?

HQL查詢。

public class UsuarioDAO : ImplementacaoPersist<Usuario>{ 

     public IList<Usuario> findByText(string text) { 
      ISession _session = BDConnect.openSession(); 
      IList<Usuario> list = (IList<Usuario>)_session.CreateQuery("from Usuario u WHERE u.nome LIKE :nome OR u.login LIKE :login") 
                     .SetParameter("nome", "%" + text + "%") 
                     .SetParameter("login", "%" + text + "%"); 
      return list; 
     } 
    } 

例外

System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>ControleUsuarios.vshost.exe</AppDomain><Exception><ExceptionType>System.InvalidCastException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Unable to cast object of type 'NHibernate.Impl.QueryImpl' to type 'System.Collections.Generic.IList`1[ControleUsuarios.Domain.Usuario]'.</Message><StackTrace> at ControleUsuarios.Implementacao.UsuarioDAO.findByText(String text) in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Implementacao\UsuarioDAO.cs:line 18 
    at ControleUsuarios.Form1.txtSearch_KeyUp(Object sender, KeyEventArgs e) in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Form1.cs:line 80 
    at System.Windows.Forms.Control.OnKeyUp(KeyEventArgs e) 
    at System.Windows.Forms.Control.ProcessKeyEventArgs(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp;amp; m) 
    at System.Windows.Forms.Control.WmKeyChar(Message&amp;amp; m) 
    at System.Windows.Forms.Control.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.TextBoxBase.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.TextBox.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(Form mainForm) 
    at ControleUsuarios.Program.Main() in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Program.cs:line 16 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.InvalidCastException: Unable to cast object of type 'NHibernate.Impl.QueryImpl' to type 'System.Collections.Generic.IList`1[ControleUsuarios.Domain.Usuario]'. 
    at ControleUsuarios.Implementacao.UsuarioDAO.findByText(String text) in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Implementacao\UsuarioDAO.cs:line 18 
    at ControleUsuarios.Form1.txtSearch_KeyUp(Object sender, KeyEventArgs e) in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Form1.cs:line 80 
    at System.Windows.Forms.Control.OnKeyUp(KeyEventArgs e) 
    at System.Windows.Forms.Control.ProcessKeyEventArgs(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp;amp; m) 
    at System.Windows.Forms.Control.WmKeyChar(Message&amp;amp; m) 
    at System.Windows.Forms.Control.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.TextBoxBase.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.TextBox.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m) 
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(Form mainForm) 
    at ControleUsuarios.Program.Main() in c:\Users\fernando\Documents\Visual Studio 2012\Projects\ControleUsuarios\ControleUsuarios\Program.cs:line 16 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</ExceptionString></Exception></TraceRecord> 
The program '[2584] ControleUsuarios.vshost.exe: Program Trace' has exited with code 0 (0x0). 
The program '[2584] ControleUsuarios.vshost.exe: Managed (v4.0.30319)' has exited with code -1 (0xffffffff). 

回答

1

您鑄造查詢對象的列表。這不是你應該如何執行你的查詢。

從您的日誌:System.InvalidCastException然後Unable to cast object of type 'NHibernate.Impl.QueryImpl' to type 'System.Collections.Generic.IList

查看doc。您的代碼應該是:

var list = _session 
    .CreateQuery("from Usuario u WHERE u.nome LIKE :nome OR u.login LIKE :login") 
    .SetParameter("nome", "%" + text + "%") 
    .SetParameter("login", "%" + text + "%") 
    .List<Usuario>(); 

附註:我想你的示例代碼不超過樣本多,但爲了以防萬一,請確保您的實際代碼不會忘記關閉/處置會話。

您也可以考慮使用其他查詢API而不是HQL。就個人而言,我傾向於使用HQL只與named queries。在代碼中,我主要使用linq-to-nhibernate。

using NHibernate.Linq; 
... 

var list = _session 
    .Query<Usuario>() 
    .Where(u => u.nome.Contains(text) || u.login.Contains(text)) 
    .ToList(); 

但你也可以使用CriteriaQueryOver

+0

我的查詢沒有ToList只有ToString,你知道爲什麼嗎? – FernandoPaiva

+0

因爲它是'List'。由於我現在只使用Linq的習慣而導致錯字。只需檢查我已鏈接的文檔,全部寫入。這通常比等待問答網站對基本錯別字的回覆要快。 –

+0

完美。現在它工作。非常感謝。! – FernandoPaiva