2017-12-31 198 views
-1

zu machen Ich schreibe eine Web-App, die ein Admin-Dashboard hat und eine Zusammenfassung aller Daten in der db hat.Ist es in Ordnung, viele Datenbank-Roundtrips in einer Controller-Aktion

MSSql wird hier verwendet.

Gibt es eine Möglichkeit, alle diese Daten aus verschiedenen Tabellen in einer Runde zu erhalten?

Ich bin auch besorgt über meine Repository-Design. Ich gebe ein IQueryable zurück, da es auf keinen Fall effizient sein wird, alle Daten als IEnumerable in den Speicher zu bekommen und mehr Filterung/Paginierung in der Mitte mit Erweiterungsmethoden durchzuführen.

Gibt es eine bessere Möglichkeit, mein Repository zu erstellen?

Hier ist meine ViewComponent Aktion (die auch eine Controller-Aktion sein kann):

public async Task<IViewComponentResult> InvokeAsync() 
    { 
     var agents = _repository.AgentData.GetAll(); 
     var applications = _repository.ApplicationData.GetAll(); 
     var paymentRequests = _repository.PaymentRequestData.GetAll(); 

     var universityCommissionCalcuator = new CommissionUniversityCalculator(0); 
     var commissionCalcuator = new CommissionReferralCalculator(universityCommissionCalcuator); 
     var commission = await _repository.AgentData.GetTotalCommissions(applications, commissionCalcuator); 

     var result = AdminSummaryMapper.ToViewModel(agents, applications, paymentRequests, commission); 

     return View(result); 
    } 

AdminSummaryMapper:

public static class AdminSummaryMapper 
{ 
    public static AdminSummaryViewModel ToViewModel(IQueryable<Agent> agents, 
                IQueryable<Application> applications, 
                IQueryable<PaymentRequest> paymentRequests, 
                Commission commission) 
    { 
     var result = new AdminSummaryViewModel() 
     { 
      TotalStudents = applications.Count(), 
      ConfirmedStudents = applications.Count(app => app.ApplicationStatus == ApplicationStatus.Confirmed), 
      UnderEvaluationStudents = applications.Count(app => app.ApplicationStatus == ApplicationStatus.UnderEvaluation), 
      TotalAgents = agents.Count(), 
      PaymentRequests = paymentRequests.Count(), 
      TotalCommission = commission.TotalComission, 
      NetCommission = commission.NetComission, 
     }; 

     return result; 
    } 
} 
+0

Stellen Sie in Ihrem Repository eine Methode ein, die alle Daten in IEnumerable für die angegebene Seite zurückgibt. Verwenden Sie EF, um alle Daten in der geringsten Anzahl von Rundreisen zu erhalten. Machen Sie einen Leistungstest und wenn die Leistung für Ihre Bedürfnisse gut genug ist, sind Sie fertig. Wenn nicht, schieben Sie die Arbeit auf eine gespeicherte Prozedur und führen Sie die Leistung erneut aus. Wenn nicht schnell genug, analysieren Sie den Ausführungsplan und finden Sie den Flaschenhals. Verwenden Sie Paging. Tun Sie keine vorzeitige Optimierung. – CodingYoshi

+0

Sehr weise Ansatz, ich habe tatsächlich versucht, Paging in mein Repository, aber es erwies sich als eine schlechte Option, denn ich brauche Filterung vor dem Paging ... also im Grunde sollte Paging eine IQueryable erweitern. –

Antwort

1

Wenn Sie mehrere Anrufe tätigen müssen die Daten von verschiedenen Orten kommt und kann nicht in einer einzigen Datenbankabfrage angefordert werden, dann ist dies kein Problem. Optimieren und cachen Sie dort, wo es Sinn macht.

+0

"Optimieren und cachen" wie? –

+0

Sie können Ihre Abfragen überprüfen und einzelne Abfragen einschließen, wo Sie können, und Sie können zwischenspeichern, indem Sie die Ergebnisse beispielsweise in der Sitzung für einen bestimmten Zeitraum speichern, um die Anzahl der Round Trips zur Datenbank zu reduzieren. Sie müssen nach verfügbaren Caching-Techniken suchen. –

+0

Sitzung! = Cache. Bitte empfehlen Sie keine Session für solche Dinge. ASP.NET Core verfügt über eine aktuelle Caching-Infrastruktur, die Sie verwenden können. –

1

Traditionell, wenn Sie viele Daten von einer Rundreise wollen, ist die Antwort für SQL Server eine gespeicherte Prozedur. Das Entitätsframework hat wahrscheinlich eine Möglichkeit, direkt auf gespeicherte Prozeduren zuzugreifen, aber unter Beibehaltung des Formats kann aus einer solchen gespeicherten Prozedur, die Daten aus mehreren Abfragen abruft, eine Sicht auf die Datenbank aufgebaut werden, so dass jede Abfrage serverseitig und dann die Ergebnisse ausgeführt wird werden auf einmal zurückgezogen.

Direkt eine gespeicherte Prozedur zugreifen:

http://www.entityframeworktutorial.net/stored-procedure-in-entity-framework.aspx

How to call Stored Procedure in Entity Framework 6 (Code-First)?

Dies erfordert, dass die gespeicherte Prozedur, die Daten zu manipulieren, so dass es wieder in einer Tabelle kommt. Entity Framework ist wirklich nicht der beste Weg, dies zu tun. Der eigentliche Zweck ist, Rookie-Fehler wie UPDATEs und DELETES ohne WHERE-Klauseln beim Hinzufügen von Auto-Completion zu erschweren.

+0

Klingt wie Hinzufügen eines anderen Repository, das solche Operationen in einem Aufruf, oder? –

+0

Im Wesentlichen. Aber wenn Sie MS SQL Server verwenden, gibt es nichts zu installieren. Öffnen Sie Management Studio, und Sie können dort eine Ansicht oder Prozedur erstellen. – NeedsAnswers

2

Sie haben nicht erwähnt, welche Art von Datenbank Sie mit EF verwenden (SQLServer, MySql, Oracle, ...).

Das Abrufen von aggregierten Daten aus einer relationalen Datenbank ist eine recht einfache Aufgabe mit SQL. Sie könnten eine Sicht definieren und Subselects wie diese hier verwenden: https://www.essentialsql.com/get-ready-to-learn-sql-server-19-introduction-to-sub-queries/

+0

Ich benutze MSSql ... hinzugefügt, dass in meiner Frage, danke! –

+0

Entschuldigung. Ich muss das verpasst haben. – LosWochos

+0

Ich bearbeite nur meine Frage nach dem Lesen Ihrer Antwort: D –

Verwandte Themen