2010-11-30 7 views
9

Ich habe eine Entität A mit einer einfachen Navigationseigenschaft B. Für jede gegebene Instanz von A erwarten wir mehrere verwandte tausend Instanzen von B.EF baut EntityCollection, aber ich (glaube ich) möchte IQueryable

Es gibt keinen Fall, in dem ich so etwas nennen:

foreach(var x in A.B) { ... } 

Stattdessen bin ich nur Interesse an einem solchen Aggregat Operationen tun als

var statY = A.B.Where(o => o.Property == "Y"); 
var statZ = A.B.Where(o => o.CreateDate > DateTime.Now.AddDays(-1)); 

Soweit ich das beurteilen kann, EF instanziiert Tausende von Referenzen auf B und führt diese Operationen im Speicher durch. Dies liegt daran, dass Navigationseigenschaften EntityCollection verwenden. Stattdessen möchte ich, dass diese Abfragen möglichst auf SQL-Ebene ausgeführt werden.

Meine derzeitige Vermutung ist, dass Navigationseigenschaften möglicherweise nicht der richtige Weg zu gehen sind. Ich bin nicht an EF gebunden, also bin ich offen für andere Ansätze. Aber ich wäre sehr daran interessiert, den richtigen Weg zu kennen, dies unter EF möglichst zu tun.

(Ich verwende EF4.)

Antwort

12

CreateSourceQuery scheint den Trick zu tun.

So würde meine Beispiele jetzt sein:

var statY = A.B.CreateSourceQuery().Where(o => o.Property == "Y"); 
var statZ = A.B.CreateSourceQuery().Where(o => o.CreateDate > DateTime.Now.AddDays(-1)); 
+0

Würde dies funktionieren, wenn A.Where (a => a.B.CreateSourceQuery(). Any (o => o.Property == "Y")); oder wird in diesem Fall ein LINQ JOIN empfohlen? –

-1

gibt es noch eine Sache, die Sie kennen sollten. Elemente, die von IQueryable <> abgeleitet sind, werden auf dem Server ausgeführt, nicht im Arbeitsspeicher. Elemente, die von IEnumerable <> abgeleitet sind, werden im Speicher ausgeführt. zum Beispiel

var someEntities = db.SomeEntities; <-- returns an IQueryable<> object. no data fetched. SomeEntities table may contain thousands of rows, but we are not fetching it yet, we are just building a query. 
someEntities = someEntities.Where(s => s.Id > 100 && s.Id < 200); <-- creates expression tree with where statement. The query is not executed yet and data is not fetched on the client. We just tell EF to perform a where filter when query will execute. This statement too returns an IQueryable<> object. 
var entities = someEntities.AsEnumerable(); <-- here we tell EF to execute query. now entities will be fetched and any additional linq query will be performed in memory. 

Sie können die Daten auch mit foreach holen, ToArray() aufrufen oder ToList <>.

Hoffnung, die Sie verstehen, was ich meine, und sorry für mein Englisch :)

+0

Ja, ich all das verstehen. Das Problem besteht jedoch darin, dass Navigationseigenschaften EntityCollections sind und IQueryable nicht implementieren. – Larsenal

+0

Diese Antwort bezieht sich nicht auf die Frage .. Frage fragt nach 'EntityCollection's auf NavigationProperties, die von den Entitäten bereitgestellt werden, während Ihre Antwort darauf fokussiert, zu erklären, wie Sie mit 'ObjectSet' umgehen können, das von' ObjectContext' bereitgestellt wird. Vereinfacht ausgedrückt fragt OP, wie man etwas in einem Rucksack findet, und Ihre Antwort erzählt, wie man einen Rucksack im Kofferraum findet. – quetzalcoatl