2010-10-31 7 views
13

In meiner Abfrage muss ich IEnumerable zurückgeben, aber ich weiß nicht, ob diese Aktion die Abfrage erneut ausführen?konvertiert die Konvertierung von IQueryable in IEnumerable die Abfrage erneut?

var data = Repository<Person>.Find().AsEnumerable();

Find() kehrt IQueryable und weil IQueryable erbt IEnumerable. Ich bezweifle, wenn AsEnumerable die wiederholte Ausführung machen.

Ich weiß, dass var data = Repository<Person>.Find().ToList() die Abfrage zweimal ausführt. Eine für Find() und zweite für Tolist()

Antwort

20

Ein IQueryable ist ein IEnumerable. Es gibt keine Bekehrung und daher keine Arbeit.

Die Arbeit passiert, wenn Sie GetEnumerator() aufrufen, entweder explizit oder durch Aufruf von foreach darauf.

Haben Sie auch bestätigt, dass Repository.Find().ToList() SQL zweimal aufruft? Das klingt nicht richtig für mich.

+0

Um dies richtiger zu machen. IQueryable ist kein IEnumerable ... aber er erbt von ihm. http://stackoverflow.com/questions/2433306/whats-the-difference-between-iqueryable-and-ienerable – Jimmyt1988

+1

@ Jimmyt1988 https://en.wikipedia.org/wiki/Is-a#Examples_of_subtyping –

11

AsEnumerable tut eigentlich nichts, außer den as Operator auf Ihr IQueryable anzuwenden. Dementsprechend wird jede zukünftige Methode, die Sie auf Ihr Objekt anwenden, den System.Linq.Enumerable-Satz von Erweiterungsmethoden im Gegensatz zu den System.Linq.Queryable-Methoden verwenden.

Es geht um verzögerte Ausführung. Nichts wird jemals gegen Ihre abfragbare Quelle ausgeführt (vermutlich die Datenbank), bis Sie versuchen aufzulisten.

Mit anderen Worten:

var data=Repository.Find().AsEnumerable() 
/* The query is only actually performed AFTER here */ 
.ToList(); 

Wenn Ihr Code:

var data=Repository.Find().ToList(); 

die Abfrage zwei Mal ausgeführt wird, ist es, weil Sie etwas falsch in Ihrem Find() -Methode tun, das sollte auf jeden Fall sollte nicht der Fall sein.

var data = Respository.Find(); 

sollte die Abfrage NULL mal ausführen.

var result = data.ToList(); // THIS is what should execute the query. 
+0

Sie hatten Recht ich hatte tolist() am ende der find-methode und ich habe das nicht bemerkt.sry – Adrakadabra

1

Denken Sie an Linq als "Stream" und Aggregatfunktion ist ein "Flush". Der Stream "linq to db" kann nur einmal gespült werden. .AsEnumerable(), .Where(), .... ist eine Möglichkeit, Abfrage vorzubereiten .ToList(), .First(), .Max() ist ein Aggregat , aber wenn Sie Aggregat nicht aufrufen, dann Ihre linq Ergebnis wird nicht ausgeführt. es fängt an zu arbeiten, nur wenn es aufgezählt wird.

ex

var result = users.Select(usr => usr.Name); 

hier nichts passieren wird, bis

1 Aggregat

result.First() 
genannt wird

oder 2 Ergebnis aufzuzählen ist

result.ToList().ForEach(...) 

yout zu beantworten Frage - .Find(), .AsEnumerable() ist keine Aggregatfunktion

Verwandte Themen