2010-11-30 8 views
9

J'ai une entité A avec une propriété de navigation simple B. Pour toute instance de A, nous attendons plusieurs milliers d'instances connexes de B.EF construit EntityCollection, mais je (crois que je) veux IQueryable

Il n'y a pas de cas où j'appelle quelque chose comme:

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

Au lieu de cela, je suis que intéressés à faire des opérations globales, telles que

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

Pour autant que je peux dire, EF instancie des milliers de références à B et effectue ces opérations en mémoire. Cela est dû au fait que les propriétés de navigation utilisent EntityCollection. Au lieu de cela, je voudrais qu'il effectue ces requêtes au niveau SQL si possible.

Mon intuition actuelle est que Propriétés de navigation peut-être pas la bonne façon de procéder. Je ne suis pas attaché à EF, donc je suis ouvert à d'autres approches. Mais je serais très intéressé de savoir la bonne façon de le faire sous EF si possible.

(j'utilise EF4.)

Répondre

12

CreateSourceQuery semble faire l'affaire.

donc mes exemples seraient maintenant:

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

Est-ce que ce travail va quand A.Where (a => a.B.CreateSourceQuery() Tout (o => o.Property == "Y").); ou est-ce que linq JOIN est recommandé dans ce cas? –

-1

Il y a une chose que vous devez savoir. Les membres qui dérivent de IQueryable <> sont exécutés sur le serveur, pas en mémoire. Les membres dérivés de IEnumerable <> sont exécutés en mémoire. par exemple

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. 

vous pouvez également récupérer les données à l'aide foreach, appelant ToArray() ou ToList <>.

espère que vous comprenez ce que je veux dire, et désolé pour mon anglais :)

+0

Oui, je comprends tout cela. Toutefois, le problème est que les propriétés de navigation sont EntityCollections et n'implémentent pas IQueryable. – Larsenal

+0

Cette réponse ne se rapporte pas à la question .. question porte sur 'EntityCollection's sur NavigationProperties exposés par les entités, alors que votre réponse se concentre sur expliquant comment vous pouvez utiliser le' 'ObjectSet' exposée par ObjectContext's. Simplifiant, OP demande comment trouver quelque chose dans un sac à dos, et votre réponse indique comment trouver un sac à dos dans le coffre de la voiture. – quetzalcoatl

Questions connexes