Ich habe eine Serverseite in c # mit Entity Framework als Provider für SQL Server entwickelt. Mein Server verwaltet eine Viele-zu-viele-Beziehung zwischen Schülern und Klassen.
%Vor%Meine Kundenseite ist in angular js mit Typscript entwickelt. Um mit dem Server synchronisiert zu werden, wird jede Serveränderung mit Push-Benachrichtigungen (Signalgeber) an die Clients übertragen.
Um eine schnellere Antwortzeit zu erhalten, behält mein Client eine Art Datenbank im Speicher (da die Datenmenge nicht so groß ist, weniger als 500 Datensätze). Ich halte eine Reihe von Studenten und für jeden von ihnen auch eine Reihe von Kursen:
%Vor%Und in diesem Objekt verfolge ich alle Studenten und ihre Kurse auf der Kundenseite.
In meiner Anwendung habe ich die Möglichkeit, mehrere Kurse aus dem gesamten System zu entfernen. Wenn diese Aktion jedoch auf der Serverseite erfolgreich abgeschlossen wird, wird die Verarbeitung auf der Clientseite schwer, wenn viele Schüler vorhanden sind. Das ist, weil ich alle entfernten Kurse durchlaufen muss und für jedes von ihnen durch das gesamte Studentenarray iterieren muss, um diese Kurse vom Studentenarray zu lokalisieren und zu entfernen. (Oder iterieren Sie die entfernten Kurse zuerst und innerhalb der Schüler iterieren) - beide sind schwer und brauchen eine Weile.
Gibt es dafür ein anderes besseres Design? Soll ich das vielleicht auf andere Weise angehen?
Es gibt ein paar Dinge, die einem einfallen:
Überprüfen Sie, ob Sie wirklich die "clientseitige Datenbank" benötigen . Ist dein Backend so langsam? Ist es nicht eine vorzeitige Optimierung ? Ich denke, die Komplexität Ihres Client-Programms wird drastisch sinken, wenn Sie diesen Teil entfernen ... Holen Sie einfach die neuesten Daten direkt vom Server, wenn Sie es brauchen.
Laden Sie die gesamte "Client-Datenbank" neu, wenn große Änderungen auftreten.
Optimieren Sie Ihre "Client-Datenbank" . Das Entfernen einiger hundert Elemente sollte nicht zu lange dauern ... Verwenden Sie angular.forEach
? Es könnte Sie erheblich verlangsamen . Hast du ein paar hundert Studenten, aber nur ein paar gestrichene Kurse? Iteriere über die Schüler und erst dann (innerhalb der Iteration) über die gelöschten Kurse. Pseudocode:
Und nicht so:
%Vor%Auf diese Weise würden Sie viel mehr iterieren und Zeit verschwenden. Aber es ist schwer, ohne Ihren Quellcode zu wissen.
Im Allgemeinen sollten Sie Ihren Code profilieren und die Leistungsprobleme festhalten. Melden Sie sich an der Konsole an, wie lange Sie für verschiedene Ansätze benötigt haben, und wählen Sie entsprechend.
Versuchen Sie, nur die Kurs-IDs im Schülerobjekt zu speichern. Auf diese Weise kann die Leistung des Entfernungsteils bewältigt werden.
Haben Sie die Kurse in einem separaten Objekt und verwenden Sie die Funktion map
, um die Kurse für den Schüler zu erhalten.
Wie in den Kommentaren vorgeschlagen, könnte Ihr Code für die Entfernung von Kursen eine Rolle spielen. Also, wenn Sie Ihre Frage bearbeiten können, wäre es hilfreich.
Natürlich gibt es ein besseres Design als nur das Durchlaufen der Arrays:)
Im Wesentlichen müssen Sie Ihr clientseitiges Array - d. h. die In-Memory-Datenbank - filtern, um die vom Server gelöschten Kurse auszuschließen (zu löschen).
Nehmen wir an, dass der Server seine Aufgabe erledigt und einige Kurse gelöscht hat und somit das Array deletedOnServer
durch SignalR gesendet hat. Dann können Sie eine clientseitige Funktion aufrufen - z. PurgeCourses
- und bereinige deine In-Memory-Datenbank. Hier ist eine mögliche Implementierung, die Array.prototype.filter () von nativem JavaScript verwendet:
jQuery.grep () ist jedoch die empfohlene Methode, da sie für eine bessere Leistung optimiert ist:
> %Vor% Beachten Sie die Verwendung von invertiert - das vierte Argument von $.grep()
.
Anstatt es im Client-Speicher zu speichern, können Sie es in einem Singleton-Objekt im Webapi-Server-Speicher speichern und auf dieses zugreifen. Das Singleton-Objekt kann die Datenbank auf Änderungen in einem Pre-File prüfen definiertes Zeitintervall (ein Code mit sehr wenigen Zeilen kann dies tun, wenn Sie ein letztes modifiziertes Feld mit einem Datetime-Vergleich verwenden). Es kann den gesamten Datensatz als Singleton wieder in den Webapi-Speicher holen.
Dies stellt auch sicher, dass jeder Client mit einer konsistenten Kopie der Daten arbeitet.
Sie sollten keine komplexen Daten clientseitig speichern. Es gibt keinen Grund dafür, dass der Client bei Verwendung eines Servers Speicherplatz findet. Wenn Ihr Server nicht schnell genug ist, müssen Sie einen besseren bereitstellen.
Die Antwort ist, dass Sie eine Wahl treffen müssen, wiederholen Sie den Prozess (langsam) auf der Client-Seite (in Anbetracht der Tatsache, dass der Endbenutzer einen schlechten PC haben kann und viel langsamer) oder denken Sie einfach eine gute Server-Strategie verarbeiten Sie Ihre Daten.
Wenn Sie die Serverarbeit reduzieren möchten, können Sie Daten abfragen und die Ergebnisse zwischenspeichern, bis sich etwas ändert. Wenn ein Benutzer etwas ändert, fragt er die Datenbank erneut ab und speichert weiterhin Daten.
Ich habe einen letzten Hinweis: Wenn Sie etwas entwickeln, müssen Sie denken, dass Sie Ihr Produkt für Milliarden von Benutzern bereitstellen werden. Sind Sie bei einer großen Anzahl von Benutzern sicher, dass die Abfrage aller Daten eine gute Idee ist?
Tags und Links asp.net-web-api angularjs c# entity-framework