Как запустить HqlBasedQuery, который возвращает несопоставленный список объектов, используя nHibernate? - PullRequest
1 голос
/ 04 марта 2009

Я хочу выполнить запрос к двум таблицам (которые отображаются в ActiveRecord). Запрос возвращает список результатов, который не может быть сопоставлен с объектом ActiveRecord (так как это пользовательская сводная информация).

Например

Dim query_str as string = "Выберите отдельный d.ID, (выберите count (1) как exp из Sales_Leads, где date_created <=: todays_date) как NbrLeads из Dealer d" </p>

Dim q As Queries.HqlBasedQuery = Новые Queries.HqlBasedQuery (GetType (ICollection), query_str) q.SetParameter ("todays_date", DateTime.Today) Dim i As ICollection = ActiveRecordMediator.ExecuteQuery (q)

Мне нужно простое выполнение SQL без возврата объекта ActiveRecord.

Таким образом, в идеале я бы мог смотреть на i («NbrResults») для каждого элемента в коллекции.

Я получаю ошибку:

Вы получили доступ к ActiveRecord класс, который не был должным образом инициализируется. Единственное объяснение что призыв к ActiveRecordStarter.Initialize () не включал System.Collections.ICollection class

Ответы [ 3 ]

2 голосов
/ 05 марта 2010

Ну, это было задано давно, но у меня есть рабочий ответ.

public static IList<T> ExecuteQuery<T>(HqlBasedQuery query)
    where T : new()
{
    query.SetResultTransformer(new NHibernate.Transform.AliasToBeanResultTransformer(typeof(T)));
        var results = (ArrayList)ActiveRecordMediator.ExecuteQuery(query);

    List<T> list = new List<T>(results.Count);
    for (int i = 0; i < results.Count; i++)
    {
        list.Add((T)results[i]);
    }

    return list;
}

Это вернет вам результаты типа T. Тип T может быть что угодно вы хотите. Типу T не нужен конструктор аргументов, и ему нужны открытые поля или свойства, которые соответствуют именам или псевдонимам столбцов в создаваемом запросе.

Мы делаем это постоянно. Особенно, если вы хотите использовать агрегатную функцию в HQL для получения агрегированных данных.

Сопутствующая функция позволит вам просто передать ваш запрос в виде строки, а также любые позиционные параметры, которые у вас могут быть:

public static IList<T> ExecuteQuery<T, U>(string hqlQuery, params object[] parameters)
        where T : new()
    {
        return ExecuteQuery<T>(new HqlBasedQuery(typeof(U), hqlQuery, parameters));
    }

Тип U - это любой тип, который является допустимым типом ActiveRecord. Это даже не тот тип, на который вы ссылаетесь. Если вы хотите заменить его, то какой-то тип, который, как вы знаете, будет действительным в сеансе, и исключит дополнительный параметр.

0 голосов
/ 09 марта 2009

Вы выходите за рамки парадигмы NHibernate, чтобы обратиться к SQL, что несколько противоречит духу ORM. Это не так уж плохо, но я бы, конечно, не стал нарушать абстракцию, если бы попытался сохранить более слабую связь.

Вы можете делать все, что хотите, с помощью простого HQL-запроса, который будет возвращать коллекцию кортежей, содержащих результаты вашего запроса. Я объяснил, как это сделать здесь

Пользовательский запрос с помощью Castle ActiveRecord

, на который вы, возможно, захотите взглянуть. Несмотря на то, что вы должны указать тип при создании нового HQLBasedQuery, NH достаточно умен, чтобы знать, что если вы не выберете экземпляр типа, он должен собрать набор результатов на основе кортежей объектов.

(IMNSHO, это все еще немного не чисто - я бы соблазнился попытаться смоделировать это отношение как объект и отобразить его соответствующим образом, но тогда мне пришлось бы привести БД в форму, чтобы она соответствовала объектной модели и это не будет летать во всех случаях.)

0 голосов
/ 05 марта 2009

Вот мое окончательное решение:

Dim query_str As String = "SELECT DISTINCT d.ID, считать (l) из LEAD при l присоединении l.Dealer как d, где l.DateCreated> = DATEADD (day, -30,: todays_date) GROUP BY d.ID «

Затем получите сеанс активной записи (или NHibernate, даже не зная, что здесь возвращается):

Затемнить ISession = activerecordmediator.GetSessionFactoryHolder (). CreateSession (GetType (ActiveRecordBase)) *

Dim q As NHibernate.IQuery = sess.CreateQuery (query_str)

q.SetParameter ("todays_date", DateTime.Today) Dim i As IList = q.List () 'получить результаты

На странице .aspx, результат может быть доступен в GridView следующим образом:

...