2

Ich benutze NHibernate 4 mit MySQL. Ich habe 2 Tische. Meine Tische sind Katze und antworten.NHibernate Elternliste mit Kind zählen

ich möchte alle Katze Datensatz (mit Antwortliste) und mit ihren cild Antworten zählen.

meine SQL-Abfrage so;

select count(t2.id) as count, cats.*from cat cats left join answer t2 ON(cats.id=t2.catId and t2.stat=0) GROUP BY(cats.id); 

Ergebnis wie folgt;

id - catName - count

1 - Buch - 5

2 - Pc - 0

3 - English - 22

4 - Kunst - 56

i habe auch diese NH-Abfrage versucht;

public class myClass { 
    public virtual int count { get; set; } 
    public virtual cat cats { get; set; } 
} 

var u = db.CreateCriteria(typeof(cat), "cats") 
     .CreateAlias("answer", "t2", NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("t2.stat", false)) 
     .SetProjection(Projections.ProjectionList() 
     .Add(Projections.Count("t2.id"), "count") 
     .Add(Projections.Group<cat>(g => g.id))); 


var list = u.SetFetchMode("answer", FetchMode.Eager) 
     .SetResultTransformer(Transformers.AliasToBean<myClass>()) 
     .List<myClass>(); 

Diese NHibernate-Abfrage gibt auch Antworten zurück. aber Katzen geben immer Null zurück. Wie kann ich meine Abfrage für dieses Ergebnis durchführen?

Edit 1 i es so, dass

public class myClass { 
    public virtual int count { get; set; } 
    public virtual catId count { get; set; } 
    public virtual cat cats { get; set; } 
} 


cat cats = null; 
answer answers = null; 

var u = db.QueryOver<cat>(() => cats) 
    .JoinQueryOver(x => x.answers,() => answers, NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("answers.stat", false)) 
    .SelectList(cv => cv 
     .SelectCount(() => answers.id) 
     .SelectGroup(c => c.id)) 
    .List<object[]>() 
    .Select(ax => new myClass 
    { 
     count = (int)ax[0], 
     catId = (int)ax[1], 
     cats = (cat)db.QueryOver<cat>().Where(w=>w.id==(int)ax[1]).Fetch(fe => fe.answers).Eager.SingleOrDefault() 
    }) 
    .ToList(); 
+0

Kleiner Offtopic Hinweis: Wenn Sie die Wahl haben, loszuwerden, die Kriterien api und mit dem [QueryOver oder Query-API] (http://stackoverflow.com/q/15020817/6666799) von NHibernate – Rabban

Antwort

0

ich diese Abfrage wie das tun können;

public class myClass { 
    public virtual int count { get; set; } 
    public virtual İnt catId { get; set; } 
    public virtual cat cats { get; set; } 
} 

cat cats = null; 
answer answers = null; 

var u = db.QueryOver<cat>(() => cats) 
    .JoinQueryOver(x => x.answers,() => answers, NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("answers.stat", false)) 
    .SelectList(cv => cv 
     .SelectCount(() => answers.id) 
     .SelectGroup(c => c.id)) 
    .List<object[]>() 
    .Select(ax => new myClass 
    { 
     count = (int)ax[0], 
     catId = (int)ax[1], 
     cats = (cat)db.QueryOver<cat>().Where(w=>w.id==(int)ax[1]).Fetch(fe=>fe.answers).Eager.SingleOrDefault() 
    }) 
    .ToList(); 
0

In Ihrem Ergebnis tun können cats ist immer null, weil die ResultTransformer versucht, die Eigenschaften durch ihre Namen abzubilden.

Bitte überprüfen Sie Ihre NHibernate Logfile. Sie werden wahrscheinlich sehen, dass Ihre Abfrage die Spalten count und id zurückgibt, aber myClass hat die Eigenschaften count und cats.

Edit:

Neuer Vorschlag:

Der bisherige Vorschlag hat nicht funktioniert, weil die Eigenschaft id vom Typ Int32 und nicht zu myClass.cat zugeordnet werden kann (die vom Typ ist cat).

Wenn Sie nicht über einen Verweis auf eine cat -object in myClass benötigen, dann können Sie es so weit ändern:

public class myClass { 
    public virtual int count { get; set; } 
    public virtual int catId { get; set; } 
} 

und haben die Projektion wie folgt aus:

.Add(Projections.Group<cat>(g => g.id), "catId")); 

Wenn Sie benötige eine Eigenschaft des Typs cat in Ihrer Ergebnisklasse Ich denke nicht, dass dies mit einer einfachen Projektion getan werden kann, aber ich könnte falsch liegen.

Edit 2:

Da Sie ein Objekt vom Typ cat in Ihrem Ergebnis benötigen Ich schlage vor, Sie es zusammen manuell nach der Abfrage, zB:

Neues Ergebnis Klasse:

public class myClassResult { 
    public virtual int count { get; set; } 
    public virtual cat cats { get; set; } 
} 

Fügen Sie diese nach Ihrer Abfragelogik hinzu:

IList<myClassResult> result = new List<myClassResult>(); 
foreach (var idWithCount in list) 
{ 
    result.Add(new myClassResult() 
    { 
    cats = catsOnlyList.FirstOrDefault(x => x.id == idWithCount.catId), 
    count = idWithCount.count 
    }); 
} 

catsOnlyList bezieht sich auf eine einfache Liste von Katzen, die Sie im Voraus erhalten müssen. Ich weiß, das ist nicht schön, aber ich glaube nicht, dass Sie in der Abfrage selbst nach cat gruppieren können.

Old Vorschlag (nicht wegen inkompatibler Typen arbeiten):

Statt

.Add(Projections.Group<cat>(g => g.id))); 

Verwendung

.Add(Projections.Group<cat>(g => g.id), "cats")); 
+0

Florian Lim es gibt dieselben Spalten zurück. Geben Sie diesen Fehler ein: Der Typ System.Int32 kann keiner Eigenschaft vom Typ cat zugewiesen werden – ASPMaker

+0

@ASPMaker Entschuldigung, ich habe die Lösung nicht getestet. Ich hätte wissen müssen, dass dies nicht funktioniert, da die Gruppierung nach ID keine Ergebniseigenschaft vom Typ "Katze" ergibt. Ich habe meine Antwort geändert. –

+0

Es tut mir leid, aber diese Änderung gibt mir nur ID. Ich möchte für diese Abfrage, muss die Anzahl der Antwort und Cat-Tabelle mit Kindern der Antwort zurückgeben. Ich erkläre alle in meiner Frage. – ASPMaker

Verwandte Themen