2009-03-25 2 views
0

Ich versuche, eine bestimmte Reihe von Daten zu erhalten, während 4 verschiedene Entitäten zusammen, um dies zu tun. Was ich habe, ist das Einrichten eines DTO getan, um zu versuchen diese Funktion zu erhalten:Wie bekomme ich eine stark typisierte Sammlung zurück, die mehrere Entitäten mit Castles ActiveRecord abfragt?

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

Jetzt dachte ich, ich SimpleQuery wie so verwenden könnte:

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

Rückkehr repository.SimpleQuery (0, 10, hql);

Meine Repository-Methode wie folgt aussieht:

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

Jetzt ist es für mich zu fragen, setzen [Active] an der Spitze meiner LatestThread Klasse. Wenn ich das mache, will es einen Primärschlüssel, und das scheint nur der falsche Weg zu sein.

Ich habe auch Bits gelesen, die sich auf das Import-Attribut beziehen, das Klassen zugewiesen wird, die nicht das DTO sind. In allen Beispielen sind nur zwei Entitäten verbunden, nicht die 4, die ich habe. Muss ich Import zu allen 4 hinzufügen? Oder gibt es etwas, um AR zu sagen, dass es eine schreibgeschützte DTO-Klasse ist? ODER mache ich das alles falsch und es gibt eine wirklich einfache Möglichkeit zu tun, was ich versuche zu tun.

TIA!

+0

Denken, was ich tun möchte, ist nicht so einfach. Sieht aus wie wenn Sie eifrig Last Einzelteile wünschen Sie alle Spalten auswählen müssen, die irgendwie bläst ... von Post p \t \t p.Comments holen beitreten \t \t holen beitreten p.Blog \t wo p.Id = 1 – rball

+0

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

Antwort

2

Fügen Sie den Import-Attribut zu Ihrem neuen Thread-Klasse

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

Und dann Abfrage Magie passiert :)

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() 

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

+0

Danke, ich werde es versuchen! – rball

+0

Ich habe diesen Beitrag schon einmal gesehen, war mir aber nicht sicher, wo der Import hingehen soll. Es scheint, dass Sie es nur auf eine der Entitäten setzen müssen? Dann sollte ich auf meinem LatestThread keine Attribute mehr benötigen, oder?Es sieht aus wie Ihr Beispiel, dass ich in der Nähe war, aber meine exe war am Ende falsch – rball

+0

Es gibt keine Liste () Methode aus Abfrage ... – rball

1

Sie können keinen Typ abfragen, der nicht zugeordnet ist (was das Attribut [ActiveRecord] tut). AFAIK Sie können NHibernate nicht dazu bringen, eine neue beliebige Objektinstanz wie diese via HQL zu erstellen (ich werde korrigiert, wenn jemand anders weiß).

Am besten erstellen Sie eine Projektionsabfrage und verfügen dann über eine Methode zum Zuordnen der Tupel, die in Instanzen Ihres Typs zurückgegeben werden.

Meine Antwort here zeigt, wie Sie eine Projektionsabfrage durchführen und sie einem anonymen Typ zuordnen. Was Sie tun möchten, ist nicht viel anders. Sie könnten dann eine Methode in einem typspezifischen Repository oder eine stark typisierte Erweiterungsmethode in das generische Repository einfügen.

+0

Mist, wirklich neu zu Nhib und Burg ar. Ich fange an, "Projektionen" zu verstehen, aber Tupel? : P Ich überprüfe es. – rball