2009-03-25 5 views
0

J'essaie d'obtenir un ensemble de données spécifique en rejoignant 4 entités différentes pour le faire. Ce que je l'ai fait est configuré un DTO pour essayer d'obtenir ce travail:Comment récupérer une collection fortement typée qui interroge plusieurs entités avec ActiveRecord de Castle?

public class LatestThread 
{ 
    private readonly string comment; 
    private readonly DateTime posted; 
    private readonly string userName; 
    private readonly int reputation; 
    private readonly int threadId; 
    private readonly string topic; 
    private readonly int userId; 
    private readonly string avatar; 

    public LatestThread(string comment, DateTime posted, string userName, int reputation, int threadId, string topic, int userId, string avatar) 
    { 
     this.comment = comment; 
     this.avatar = avatar; 
     this.userId = userId; 
     this.topic = topic; 
     this.threadId = threadId; 
     this.reputation = reputation; 
     this.userName = userName; 
     this.posted = posted; 
    } 

    public string Comment 
    { 
     get { return comment; } 
    } 

    public DateTime Posted 
    { 
     get { return posted; } 
    } 

    public string UserName 
    { 
     get { return userName; } 
    } 

    public int Reputation 
    { 
     get { return reputation; } 
    } 

    public int ThreadId 
    { 
     get { return threadId; } 
    } 

    public string Topic 
    { 
     get { return topic; } 
    } 

    public int UserId 
    { 
     get { return userId; } 
    } 

    public string Avatar 
    { 
     get { return avatar; } 
    } 
} 

Maintenant, je pensais que je pouvais utiliser SimpleQuery comme ceci:

string hql = string.Format("select new LatestThread(m.Comment, m.Posted, u.UserName, u.Reputation, t.Id, t.Topic, u.Id, u.Avatar) from Thread as t inner join Message as m on t.Id = m.ThreadId inner join User as u on u.Id = m.PostedById inner join Activity as a on a.Id = t.ActivityId where a.Lineage like '{0}%' order by t.LastPosted desc", activityLineage); 

repository.SimpleQuery retour (0, 10, hql)

Ma méthode référentiel ressemble:

public virtual IList<T> SimpleQuery<T>(int firstResult, int maxResults, string hql, params object[] parameters) 
    { 
     var query = new SimpleQuery<T>(hql, parameters); 
     query.SetQueryRange(firstResult, maxResults); 
     return query.Execute(); 
    } 

Maintenant, il est demander pour moi de mettre [ActiveRecord] au sommet de ma classe LatestThread. Quand je fais cela, il veut une clé primaire, et cela semble juste être la mauvaise route.

J'ai également lu des bits qui font référence à l'attribut Import donné aux classes qui ne sont pas le DTO. Dans tous les exemples, il n'y a que deux entités qui sont jointes, pas les 4 que j'ai. Ai-je besoin d'ajouter Import à tous les 4? Ou y at-il quelque chose à dire à AR que c'est une classe DTO en lecture seule? Ou est-ce que je fais tout faux et il y a une manière vraiment facile de faire ce que j'essaye de faire.

TIA!

+0

Penser ce que je veux faire est de ne pas C'est facile. On dirait que si vous voulez des éléments de charge désireux que vous devez sélectionner toutes les colonnes qui souffle un peu ... de post p \t \t join fetch p.Comments \t \t join fetch p.Blog \t où p.Id = 1 – rball

+0

http://trappedinaworldofcode.wordpress.com/2008/03/19/strongly-typed-results-from-nhibernate-hql-projection-query/ – rball

Répondre

2

Ajoutez l'attribut d'importation à votre nouvelle classe Thread

[Import(typeof(LatestThread), "LatestThread")] 
[ActiveRecord("Thread")] 
public class Thread : ActiveRecordBase<Thread> { /* blah blah */ } 

Et puis, la magie de la requête arrive :)

string hql = string.Format("select new LatestThread(m.Comment, m.Posted, u.UserName, u.Reputation, t.Id, t.Topic, u.Id, u.Avatar) from Thread as t inner join Message as m on t.Id = m.ThreadId inner join User as u on u.Id = m.PostedById inner join Activity as a on a.Id = t.ActivityId where a.Lineage like '{0}%' order by t.LastPosted desc", activityLineage); 

SimpleQuery<LatestThread> query = new SimpleQuery<LatestThread>(typeof(Thread), hql); 
LatestThread[] results = query.Execute() 

Source: http://www.kenegozi.com/Blog/2006/10/08/projection-using-activerecords-importattribute-and-hqls-select-new-clause.aspx

+0

Merci, je vais essayer! – rball

+0

J'ai effectivement vu ce post avant, mais je ne savais pas où diable mettre l'importation. Il semble que vous avez juste besoin de le mettre sur l'une des entités? Puis de retour sur mon LatestThread je ne devrais pas besoin d'attributs non?Il semble de votre exemple que j'étais proche, mais mon exe était erroné à la fin – rball

+0

Il n'y a pas de liste () méthode hors requête ... – rball

1

Vous ne pouvez pas interroger un type qui n'est pas mappé (ce que fait l'attribut [ActiveRecord]). AFAIK vous ne pouvez pas obtenir NHibernate pour créer une nouvelle instance d'objet arbitraire comme cela via HQL (je peux être corrigé si quelqu'un sait le contraire). Votre meilleur pari est de faire une requête de projection et ensuite avoir une méthode pour mapper les tuples retournés dans les instances de votre type.

Ma réponse here montre comment faire une requête de projection et la mapper à un type anonyme; ce que tu veux faire n'est pas très différent. Vous pouvez ensuite placer une méthode pour le faire dans un référentiel spécifique au type ou une méthode d'extension fortement typée dans le référentiel générique.

+0

Merde, vraiment nouveau pour nhib et ar's castle. Je commence à comprendre les "projections" mais les tuples? : P Je vais vérifier. – rball

Questions connexes