NHibernate: Как вернуть скалярное значение, используя CreateSQLQuery с собственным SQL? - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь получить скалярное значение, используя собственный запрос 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();

И соответствующий SQL из SQL Server Profiler является правильным, и это возвращает желаемое значение

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'

Но typeof deptName равно System.Collections.IList {System.Collections.Generic.List<object>}, а также, когда я пытаюсь получить доступ к deptName с помощью deptName[0].ToString(), оно возвращает System.Object[] вместо фактического значение.

Ответы [ 2 ]

1 голос
/ 31 января 2020

Вы должны сказать, что хотите только скаляр:

var deptName = session.CreateSQLQuery("...").UniqueResult<string>();
0 голосов
/ 31 января 2020

Ваш код верен, но в конце, возвращая значение, вы конвертируете скалярный вывод в список. Соблюдайте .List() в конце вашего кода. Вот в чем проблема.

Хотя ваш запрос SQL выбирает только один столбец из одной строки, NHibernate не может узнать, что означает . Вы можете указать NHibernate преобразовать вывод в скалярное значение, заменив .List() call на .UniqueResult<string>() call.

Вызов .UniqueResult<string>() снова повторяется в два раза. UniqueResult не вернет скаляр, он может вернуть одну строку (экземпляр сущности) на основе переданного ему параметра generi c. Если соответствующая строка не найдена, она вернет null. Если найдено несколько строк, он выдаст 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;
}

Далее, чтобы вместо него было возвращено одно скалярное значение строки, вам нужно использовать generi c перегрузка UniqueResult<T>. Вам нужно указать параметр generi c (<string> в вашем случае; зависит от того, что вы возвращаете).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...