Requête personnalisée avec Castle ActiveRecord
-
08-07-2019 - |
Question
J'essaie de comprendre comment exécuter une requête personnalisée avec Castle ActiveRecord.
J'ai pu exécuter une requête simple qui renvoie mon entité, mais ce dont j'ai vraiment besoin, c'est la requête suivante (avec le champ personnalisé défini):
sélectionnez count (1) en tant que cnt, données de workstationevent où serverdatetime > =: minDate et serverdatetime < : maxDate et userId = 1 groupe de données ayant un compte (1) > : seuil
Merci!
La solution
Dans ce cas, ce que vous voulez, c'est HqlBasedQuery
. Votre requête sera une projection. Par conséquent, vous obtiendrez un ArrayList
de tuples contenant les résultats (le contenu de chaque élément de ArrayList dépendra de la requête, mais pour plusieurs la valeur sera objet []
).
HqlBasedQuery query = new HqlBasedQuery(typeof(WorkStationEvent),
"select count(1) as cnt, data from workstationevent where
serverdatetime >= :minDate and serverdatetime < :maxDate
and userId = 1 group by data having count(1) > :threshold");
var results =
(ArrayList)ActiveRecordMediator.ExecuteQuery(query);
foreach(object[] tuple in results)
{
int count = (int)tuple[0]; // = cnt
string data = (string)tuple[1]; // = data (assuming this is a string)
// do something here with these results
}
Vous pouvez créer un type anonyme pour conserver les résultats de manière plus significative. Par exemple:
var results = from summary in
(ArrayList)ActiveRecordMediator.ExecuteQuery(query)
select new {
Count = (int)summary[0], Data = (string)summary[1]
};
Les résultats contiendront maintenant une collection de types anonymes avec les propriétés Count
et Données
. Sinon, vous pouvez créer votre propre type de résumé et le renseigner également.
ActiveRecord a également le ProjectionQuery
qui fait à peu près la même chose mais ne peut renvoyer que les propriétés mappées réelles plutôt que des agrégats ou des fonctions comme vous le pouvez avec HQL.
Autres conseils
Sachez cependant que si vous utilisez ActiveRecord 1.0.3 (RC3) comme je le faisais, cela entraînera une exception d'exécution InvalidCastException. ActiveRecordMediator.ExecuteQuery retourne une ArrayList et non une ICollection générique. Donc, pour que cela fonctionne, il suffit de changer cette ligne:
var results = (ICollection<object[]>) ActiveRecordMediator.ExecuteQuery(query);
à
var results = (ArrayList) ActiveRecordMediator.ExecuteQuery(query);
et cela devrait fonctionner.
Notez également que l'utilisation de count (1) dans votre instruction hql fera en sorte que la requête renvoie un ArrayList of String au lieu d'un ArrayList d'objet [] (ce que vous obtenez en utilisant count (*).)
Je pensais juste que je signalerais ceci afin de tout documenter au même endroit.