Ich habe in den letzten Monaten eine Webapp mit Linq zu NHibernate entwickelt, aber habe das SQL, das es generiert, bis jetzt nicht profiliert. Bei Verwendung von NH Profiler scheint der folgende Codeabschnitt die Datenbank mehr als 3.000 Mal zu erreichen, wenn der Linq-Ausdruck ausgeführt wird.Linq zu NHibernate generiert 3.000 + SQL-Anweisungen in einer Anfrage!
var activeCaseList = from c in UserRepository.GetCasesByProjectManagerID(consultantId)
where c.CompletionDate == null
select new { c.PropertyID, c.Reference, c.Property.Address, DaysOld = DateTime.Now.Subtract(c.CreationDate).Days, JobValue = String.Format("£{0:0,0}", c.JobValue), c.CurrentStatus };
Wenn das Repository-Methode wie folgt aussieht:
public IEnumerable<Case> GetCasesByProjectManagerID(int projectManagerId)
{
return from c in Session.Linq<Case>()
where c.ProjectManagerID == projectManagerId
select c;
}
Es erscheint zuerst die anfängliche Repository Abfrage auszuführen, durchläuft dann alle Ergebnisse zu überprüfen, ob die CompletionDate null ist, sondern eine Ausstellung Abfrage, um c.Property.Address zuerst zu erhalten.
Wenn also die anfängliche Abfrage 2000 Datensätze zurückgibt, auch wenn nur fünf von ihnen kein CompletionDate haben, löst sie immer noch eine SQL-Abfrage aus, um die Adressendetails für die 2000 Datensätze zurückzuholen.
Die Art, wie ich dies vorgestellt hatte funktionieren würde, ist, dass es sie alle der WHERE und SELECT-Klauseln und einfach fusionieren, so dass die inital Abfrage wäre wie beurteilen würde:
SELECT ... WHERE Projectmanager = @ p1 AND CompleteDate ist NICHT NULL
Das würde 5 Datensätze ergeben, und dann könnte es die weiteren 5 Abfragen auslösen, um die Adressen zu erhalten. Erwarte ich hier zu viel oder mache ich einfach etwas falsch?
Anthony
Prost, das ist viel besser! – littlecharva