2016-05-27 3 views
0

den folgenden Code-Schnipsel vor:IEnumerable <T> viel länger als IQueryable <T> wobei die Ergebnisse zurück

public interface IRepository<T> where T : class 
{ 
    IQueryable<T> GetAll(); 
    ... 
} 

public class EmployeeRepository<T> : IRepository<T> where T : class 
{ 
    private Employee db; 
    private DbSet<T> dbSet; 

    public EmployeeRepository() 
    { 
     db = new Employee(); 
     dbSet = db.Set<T>(); 
    } 
    public virtual IQueryable<T> GetAll() 
    { 
     return dbSet; 
    } 
} 

In der Steuerung implementieren ich es als:

private IRepository<Employee> employeeRepo = null; 

public HomeController() 
{  
    employeeRepo = new EmployeeRepository<Employee>(); 
} 

den obigen Code verwenden, wenn ich rufe die employeeRepo.GetAll() Methode in meiner MVC-Controller-Aktion bekomme ich das Ergebnis sofort in der Ansicht nicht mehr als 2 Sekunden, um die Datensätze von rund 500 Zeilen. Wenn ich den gleichen Code zu

public virtual IEnumerable<T> GetAll() 
{ 
    return dbSet.ToList(); 
} 

dann ändern dauert es etwa 30 Sekunden die gleiche Menge an Zeilen aus exakt den gleichen Tisch zurückzukehren.

Also meine Frage ist, warum dauert IEnumerable<T> so viel länger als IQueryable<T>.

I Die meisten Beispiele online-Repository-Muster Einsatz gesehen habe IEnumerable<T> so sicher, dass ich nicht, ob ich unter Verwendung IQueryable<T>

Update, um den richtigen Weg nach unten werde:

public ActionResult Index() 
{ 
    var allEmployees = employeeRepo.GetAll(); 

    return View(allEmployees); 
} 

die SQL ausgeführt wird, ist

SELECT EMPLOYEEID, EMPLOYEENAME, EMPLOYEEDOB, EMPLOYEETELEPHONE FROM [DBO].[EMPLOYEE] 

die genaue Anzahl der zurückgegebenen Zeilen ist 507. ich alle von ihnen, weil sie in einer Dropdown-Liste gehen

+0

Sind Sie auf irgendwelche '.Where (...)' Klauseln auf das stecken? –

+0

@ LasseV.Karlsen no '.Where()' Klausel – Code

+0

Und wenn Sie sagen, Sie erhalten das Ergebnis sofort, füllen Sie tatsächlich die Ansicht und produzieren den endgültigen HTML * in diesen 2 Sekunden *, oder meinst du, dass die Methode GetAll innerhalb von 2 Sekunden zurückgegeben? –

Antwort

1

Ich glaube, das ist vergleichbar mit der Frage here. Im Wesentlichen wird IQueryable versuchen und in der Datenbank ausführen, da dies die Linq-to-SQL-Schnittstelle ist und IEnumerable zuerst alles in den Speicher laden muss. Hier ist ein weiterer detailed explanation auf den Unterschied mit Performance-Code.

+1

'IEnumerable ' auf seinem eigenen wird nicht alles in den Speicher laden, die 'ToList() 'in der OP wird sicherlich dazu führen, dass es. –

+0

@MatthewWatson also, wenn ich '.ToList()' entfernen, wird es mir keine Probleme – Code

+0

@Code Nun, es sollte nicht tun - hängt davon ab, ob Sie es mehrmals später wiederholen oder nicht. –

2

dies ist, weil innerhalb Get() Sie ToList() aufrufen, was bedeutet, dass Sie tatsächlich die Abfrage ausführen. In der ersten Implementierung (IQueryable) wird die Abfrage nicht ausgeführt. Es wird ausgeführt, bis Sie ToList() anrufen

+0

Aber 30 Sekunden ist eine sehr lange Zeit .. Ist das normal? – Code

+0

Hängt von der Abfrage und der Datenbankinstanz ab. Fragen Sie nach nicht indizierten Spalten? Wie viele Zeilen sind betroffen? Verfügt Ihr Datenbankserver über genügend Ressourcen? Ist es das einzige, was auf dem Server läuft? Ist die Datenbank remote oder lokal? Wenn es fern ist, ist es vor Ort oder außerhalb? Verfügen Sie über ausreichende Bandbreite zwischen dem Webserver und dem Datenbankserver? Die Fragen gehen weiter und weiter. –