2010-04-12 6 views
5

Ich bin mit Wrapper einige Daten aus der Tabelle Benutzer erhaltenLinq to NHibernate Wrapper Ausgabe, in der Anweisung

IQueryable<StarGuestWrapper> WhereQuery =  
session.Linq<User>().Where(u => u.HomeClub.Id == clubId && u.IsActive).Select(
        u => 
        new StarGuestWrapper() 
         { 
          FullName = u.Name + " " + u.LastName, 
          LoginTime = u.SomeDateTime, 
          MonthsAsMember = u.SomeIntergerValue, 
          StarRating = u.SomeOtherInteregValue, 
          UserPicture = u.Photo.PhotoData, 
          InstructorFullName = u.SomeInstructorName, 
          TalkInteractionDuringSession = u.SomeBoolValue, 
          GoalInteractionDuringSession = u.SomeOtherBoolValue 
         }); 

ich dies ohne Probleme verwenden, wie ein IQueryable so kann ich, bevor sie tatsächlich läuft die Abfrage nützliche Dinge tun . Wie:

WhereQuery.Skip(startRowIndex).Take(maximumRows).ToList(); 

und so weiter.

Das Problem tritt auf, wenn die Anweisung 'where' für die Abfrage verwendet wird. Zum Beispiel:

WhereQuery.Where(s => s.StarRating == 1) 

wird eine Ausnahme im laufenden Betrieb werfen, dass ‚Typ zu einem höheren‘ existiert nicht in Benutzertabelle - natürlich es nicht, es ist eine Wrapper-Eigenschaft. Es wird funktionieren, wenn ich Abfrage von

WhereQuery.AsEnumerable().Where(s => s.StarRating == 1) 

materialisieren, aber dann verliert es alle sens der Verwendung von IQueryable und ich will nicht, dies zu tun.

Was ist seltsam und interessant, dass nicht alle Eigenschaften von Wrapper Fehler, alle Bool-Werte können in where Anweisung verwendet werden. Beispiel:

WhereQuery.Where(s => s.TalkInteractionDuringSession) 

Es funktioniert in EntityFramework, warum bekomme ich diesen Fehler in NHibernate und wie es zum Laufen zu bringen, wie ich es will?

+0

Wie beabsichtigen Sie, (was den Datenspeicher verwendet) auf etwas abzufragen, das sich nicht im Datenspeicher befindet? Die einzige Möglichkeit, alle mit StarRating = 1 zu finden, besteht darin, über alles aufzuzählen. –

+0

@Lasse Sie scheinen nicht zu verstehen, wie ORM funktioniert, es ist eine Abfrage nicht eine Sammlung, es enthält keine Daten es Datenbank für diese Daten abfragt. Beachten Sie die hardcoded Werte in diesem Wrapper, es ist nur ein Beispiel, ich schreibe stattdessen u.SomeValue. – Jacob

+0

Es * war * eine Abfrage, bevor Sie einen neuen Ergebnistyp erstellt haben. An diesem Punkt brechen Sie die Verbindung zum Datenspeicher auf. Das Ergebnis Ihrer SELECT-Anweisung ist nicht mehr abfragbar. Sie können weiterhin .Where-Klauseln hinzufügen. Das ist das gleiche wie diese Art von Code: SELECT * FROM (magischer C# -Code hier von (SELECT * FROM yurtable)) –

Antwort

2

Bedenken Sie, dass der ältere nHibernate Linq-Anbieter nur eine Teilimplementierung ist und nicht mehr aktiv bearbeitet wird. Ein neuer und vollständigerer linq-Provider wird jetzt entwickelt und wird Teil von NH3.0 sein (Sie können den Trunk auschecken und ihn erstellen, um zu sehen, ob er dieses Problem behebt).

Ich empfehle, den Code so zu ändern, dass ToList() aufgerufen wird, wenn Sie explizit auf die Datenbank zugreifen möchten. Sie geben eine Anfrage mit einer zukünftigen Wertigkeit von Ihrem Repository zurück, und zu diesem Zeitpunkt könnte irgendetwas technisch mit der Abfrage geschehen. Sogar EF und LINQ2SQL können keine mögliche linq-Abfrage in SQL übersetzen.

Ich weiß, das ist nicht das, was Sie tun können, aber ich denke, Sie versuchen, den Rahmen zu biegen, etwas in einer Weise zu tun, die überhaupt nicht natürlich ist.

+0

Chris, was ist die Version der letzten Linq dll? 2.0? – NetSide

+0

Ich würde es nicht wissen, Sie müssten wahrscheinlich auf der NHUsers-Liste –

+0

fragen, sollte NH3 wahrscheinlich erwähnen.0 nur Alpha Release und ist wahrscheinlich ziemlich stabil, wenn Sie es ausprobieren möchten. –