简体   繁体   English

NHibernate:如何使用带有本机 SQL 的 CreateSQLQuery 返回标量值?

[英]NHibernate: How to return scalar value using CreateSQLQuery with native SQL?

I'm trying to get a scalar value using a native SQL query and my statement looks like我正在尝试使用本机 SQL 查询获取标量值,我的语句看起来像

var deptName =session.CreateSQLQuery(@"Select d.deptName from employee e,dept d Where e.deptId=d.deptID and e.EmpID=?")
                    .AddScalar("deptName", NHibernateUtil.String)
                    .SetCacheable(true)
                    .SetCacheMode(CacheMode.Normal)
                    .SetParameter(0, "12345").List();

And the corresponding SQL from SQL Server Profiler is correct and it is returning the desired value并且来自 SQL Server Profiler 的相应 SQL 是正确的,并且它正在返回所需的值

exec sp_executesql N'select d.deptName from employee e, dept d
                            where e.empId=@p0 
                            and e.deptId=d.deptId',N'@p0 nvarchar(4000)',@p0=N'12345'

But the typeof deptName is System.Collections.IList {System.Collections.Generic.List<object>} and also when I try to access the deptName with deptName[0].ToString() it is returning System.Object[] instead of the actual value.typeof deptNameSystem.Collections.IList {System.Collections.Generic.List<object>}并且当我尝试访问deptNamedeptName[0].ToString()它返回System.Object[]而不是实际值。

你需要告诉它你只想要标量:

var deptName = session.CreateSQLQuery("...").UniqueResult<string>();

Your code is all correct, but at the end while returning the value, you are converting the scalar output to list.您的代码都是正确的,但最后在返回值时,您将标量输出转换为列表。 Observe the .List() at the end of your code.观察代码末尾的.List() That is the problem.那就是问题所在。

Though your SQL query selects only one column from one row, NHibernate have no way to learn that that is the case.虽然你的SQL查询选择从一行只有一列,NHibernate的没有办法得知这种情况。 You can instruct NHibernate to convert the output to scalar value by replacing .List() call with .UniqueResult<string>() call.您可以通过将.List()调用替换为.UniqueResult<string>()调用来指示 NHibernate 将输出转换为标量值。

The .UniqueResult<string>() call is again two fold. .UniqueResult<string>()调用又是两次。 The UniqueResult will not return scalar, it may return single row (entity instance) based on generic parameter passed to it. UniqueResult不会返回标量,它可能会根据传递给它的泛型参数返回单行(实体实例)。 If no matching row found, it will return null .如果没有找到匹配的行,它将返回null If multiple rows found, it will throw NonUniqueResultException as seen in the source code here :如果发现多行,它会抛出NonUniqueResultException在源代码中看到在这里

 internal static object UniqueElement(IList list) { int size = list.Count; if (size == 0) { return null; } object first = list[0]; for (int i = 1; i < size; i++) { if (list[i] != first) { throw new NonUniqueResultException(size); } } return first; }

Further, to make it return single scalar value instead of row, you need to use generic overload UniqueResult<T> .此外,要使其返回单个标量值而不是行,您需要使用泛型重载UniqueResult<T> You need to specify generic parameter ( <string> in your case; depends on what you are returning) to it.您需要为其指定通用参数(在您的情况下为<string> ;取决于您要返回的内容)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM