2009-01-27 6 views
4

Supposons que nous avons une méthode comme ceci:Charge-t-il les données de la base de données?

où le contexte
public IEnumerable<T> FirstMethod() 
{ 
    var entities = from t in context.Products 
        where {some conditions} 
        select t; 

    foreach(var entity in entities) 
    { 
     entity.SomeProperty = {SomeValue}; 
     yield return entity; 
    } 
} 

est un DataContext qui est généré par LINQ to SQL Designer. Est-ce que "FirstMethod" charge les données en mémoire à partir de la base de données (à cause de la boucle foreach) ou va-t-il les différer jusqu'à ce qu'une autre méthode foreach qui ne possède pas "yield return" soit trouvée Suivant?

public void SecondMethod() 
{ 
    foreach(var item in FirstMethod()) 
    { 
     {Do Something} 
    } 
} 
+0

(mis à jour re votre commentaire, ajoutée ici pour une meilleure visibilité) –

Répondre

6

Ce dernier (différé); FirstMethod est un bloc d'itérateur (à cause de yield return); cela signifie que vous avez une chaîne d'itérateurs. Rien n'est lu tant que l'appelant final commence l'itération des données; puis chaque enregistrement est lu successivement pendant les appelsforeach de l'appelant final (entre lesquels la connexion/commande est ouverte).

Le using qui entoure foreach (sous le capot) veille à ce que la connexion est fermée lorsque le foreach est abandonné à mi-chemin de passage.

Si vous voulez pour charger les données antérieures, utilisez .ToList() ou .ToArray() pour tamponner les données localement - mais notez que cette pause « composition » - à savoir l'appelant ne peut plus ajouter Where supplémentaires clauses etc (qu'ils peuvent si il renvoie un IQueryable<T> brut).


Re votre question:

public IEnumerable<T> FirstMethod() 
{ 
    var entities = from t in context.Products 
        where {some conditions} 
        select t; 

    foreach(var entity in entities.AsEnumerable()) 
    { 
     entity.SomeProperty = {SomeValue}; 
     yield return entity; 
    } 
} 

Le AsEnumerable est la clé ici; il termine la chaîne composable IQueryable<T> et utilise LINQ-to-Objects pour le reste.

+0

Vous apprenez quelque chose de nouveau tous les jours, je suppose. Je vais supprimer ma réponse: P –

+0

J'ai vérifié le journal de contexte de données et il semble que d'autres clauses linq ne se traduiront pas en commandes SQL. Y a-t-il un moyen d'y arriver? Tout ce que je veux, c'est définir une propriété (ce n'est pas une colonne) quand l'ensemble de résultats retourne d'une méthode IQueryable . – mrtaikandi

+0

Oui - Je mettrai à jour –

1

Le chargement est différé jusqu'à ce que la méthode GetEnumerator est appelée sur les entités requête et ne se produira pas tant que la méthode GetEnumerator est appelée sur le IEnumerable <T> vous retournez.

2

En bref, il ne se charge pas jusqu'à ce que SecondMethod effectue l'itération ...

Lire here pour plus ...

Questions connexes