如何将 IList 与 HQL 查询和 NHibernate 一起使用?
How to use IList with HQL Query and NHibernate?
我正在尝试使用 NHibernate 执行 HQL 查询。当我尝试执行查询时,它抛出异常,我无法理解问题所在。
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; m)
at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp; m)
at System.Windows.Forms.Control.WmKeyChar(Message&amp; m)
at System.Windows.Forms.Control.WndProc(Message&amp; m)
at System.Windows.Forms.TextBoxBase.WndProc(Message&amp; m)
at System.Windows.Forms.TextBox.WndProc(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&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; m)
at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp; m)
at System.Windows.Forms.Control.WmKeyChar(Message&amp; m)
at System.Windows.Forms.Control.WndProc(Message&amp; m)
at System.Windows.Forms.TextBoxBase.WndProc(Message&amp; m)
at System.Windows.Forms.TextBox.WndProc(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&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).
您正在将查询对象转换为列表。这不是执行查询的方式。
来自您的日志: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>();
旁注:我想您的示例代码只是一个示例,但以防万一,请确保您的实际代码不会忘记 close/dispose 会话。
您也可以考虑使用除 HQL 之外的其他查询 API。就个人而言,我倾向于仅将 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();
我正在尝试使用 NHibernate 执行 HQL 查询。当我尝试执行查询时,它抛出异常,我无法理解问题所在。
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; m)
at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp; m)
at System.Windows.Forms.Control.WmKeyChar(Message&amp; m)
at System.Windows.Forms.Control.WndProc(Message&amp; m)
at System.Windows.Forms.TextBoxBase.WndProc(Message&amp; m)
at System.Windows.Forms.TextBox.WndProc(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&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; m)
at System.Windows.Forms.Control.ProcessKeyMessage(Message&amp; m)
at System.Windows.Forms.Control.WmKeyChar(Message&amp; m)
at System.Windows.Forms.Control.WndProc(Message&amp; m)
at System.Windows.Forms.TextBoxBase.WndProc(Message&amp; m)
at System.Windows.Forms.TextBox.WndProc(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&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).
您正在将查询对象转换为列表。这不是执行查询的方式。
来自您的日志: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>();
旁注:我想您的示例代码只是一个示例,但以防万一,请确保您的实际代码不会忘记 close/dispose 会话。
您也可以考虑使用除 HQL 之外的其他查询 API。就个人而言,我倾向于仅将 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();