2009-03-04 3 views
1

Ich möchte eine Abfrage für zwei Tabellen (die zufällig in ActiveRecord zugeordnet sind) ausführen. Die Abfrage gibt eine Ergebnisliste zurück, die keinem ActiveRecord-Objekt zugeordnet werden kann (da es sich um benutzerdefinierte Aggregatdaten handelt).Wie führe ich eine HqlBasedQuery aus, die eine nicht zugeordnete Liste von Objekten mit nHibernate zurückgibt?

Zum Beispiel

Dim query_str as string = "select distinct d.ID, (SELECT COUNT (1), wie von exp Sales_Leads DATE_CREATED wo < =: todays_date) als NbrLeads von Anbieter d"

Dim q Als Queries.HqlBasedQuery = New Queries.HqlBasedQuery (GetType (ICollection), query_str) q.SetParameter ("todays_date", DateTime.Today) Dim i As ICollection = ActiveRecordMediator.ExecuteQuery (q)

Was ich Ich suche nach einfacher Ausführung von SQL, ohne ein ActiveRecord-Objekt zurückgegeben.

Also, im Idealfall würde ich in der Lage sein, ich ("NbrResults") für jedes Element in der Sammlung zu betrachten.

Der Fehler Ich erhalte ist:

Sie haben eine Active Klasse zugegriffen, die nicht richtig initialisiert wurde. Die einzige Erklärung ist dass der Aufruf von ActiveRecordStarter.Initialize() nicht System.Collections.ICollection Klasse enthalten waren

Antwort

0

Hier ist meine endgültige Lösung war:

Dim query_str As String = „SELECT DISTINCT d.ID, count (l) von LEAD als l bei l.Dealer als d mit l.DateCreated> = DATEADD (Tag, -30,: todays_date) GROUP BY d.ID "

Dann besorgen Sie sich den aktiven Datensatz Sitzung (oder NHibernate, immer noch nicht einmal wissen, was hier zurückgegeben wird):

Dim sess Wie ISession = activerecordmediator.GetSessionFactoryHolder(). Create (GetType (ActiveRecordBase))

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

q.SetParameter ("todays_date" , DateTime.Today) Dim i As IList = q.List() 'Ergebnisse erhalten

in der ASPX-Seite, kann das Ergebnis wie so in einem Gridview zugegriffen werden:

0

Yo Wir verlassen das NHibernate-Paradigma, um auf SQL zurückzugreifen, was etwas gegen den Geist von ORM ist. Es ist nicht per se schlecht, aber ich würde es sicherlich vermeiden, die Abstraktion zu durchbrechen, wenn ich versuchen könnte, eine lockere Verbindung aufrechtzuerhalten.

Sie können tun, was Sie wollen, mit einer geraden HQL-Abfrage, die eine Sammlung von Tupeln zurückgibt, die die Ergebnisse Ihrer Abfrage enthalten. Ich erklärte, wie diese

Custom query with Castle ActiveRecord

hier zu tun, die Sie auf einen Blick haben möchten.Obwohl Sie einen Typ angeben müssen, wenn Sie eine HQLBasedQuery neu erstellen, ist NH klug genug zu wissen, dass wenn Sie keine Typinstanz auswählen, eine Ergebnismenge basierend auf Objekttupeln zusammengestellt werden soll. Wenn ich versucht bin, diese Beziehung als ein Objekt zu modellieren und es entsprechend zu mappen, dann müsste ich die DB in Form bringen, um sie dem Objektmodell anzupassen und das wird nicht in allen Fällen fliegen.)

2

Nun, das wurde vor langer Zeit gefragt, aber ich habe eine funktionierende Antwort.

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; 
} 

Dies gibt Ihnen Ergebnisse vom Typ T Typ T zurück kann alles sein Sie wollen. Typ T benötigt einen Konstruktor ohne Argumente und benötigt öffentliche Felder oder Eigenschaften, die den Spaltennamen oder Aliasen in der von Ihnen erstellten Abfrage entsprechen.

Wir machen das die ganze Zeit. Insbesondere, wenn Sie die Aggregatfunktion in HQL verwenden möchten, um aggregierte Daten zu erzeugen.

Eine Begleiter-Funktion ermöglicht es Ihnen, nur als String in der Abfrage übergeben sowie alle Positionsparametern Sie haben könnten:

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

Typ U ist jede Art, die ein gültiger Active Typ ist. Es muss nicht einmal einer der Typen sein, auf die Sie verweisen. Wenn Sie möchten, dass Sie es ersetzen können, wird ein Typ, von dem Sie wissen, dass er in der Sitzung gültig sein wird, und den zusätzlichen Parameter abziehen.

Verwandte Themen