Laden...

Wie damit umgehen, dass zunächst nur ein kleiner Teil der Daten und der Rest bei Bedarf geladen wird

Erstellt von THQ vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.602 Views
T
THQ Themenstarter:in
68 Beiträge seit 2011
vor 12 Jahren
Wie damit umgehen, dass zunächst nur ein kleiner Teil der Daten und der Rest bei Bedarf geladen wird

Guten morgen,

und zwar habe ich derzeit folgendes Problem.

Ich habe eine Art kleinen Cache, welcher aus generischen Typen besteht.
In diesem Cache führe ich eine Liste mit diesen Typen als Datentyp.

Nun bekomme ich eine "neue Instanz" einer Klasse vom gleichen Typ, die es allerdings schon in dem Cache gibt. Nun will ich die Eigenschaften von der vorhandenen Klasse von der neuen Klasse übernehmen lassen, da ich den alten Eintrag nicht einfach löschen kann und den neuen hinzufügen kann.

Gibt es eine Möglichkeit den reinen Inhalt einer Klasse auf eine andere zu übertragen?
z.B. via Reflection?

mfg thq

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

per Reflection ist es möglich die Eigenschaften zu übertragen, per (binärer) Serialisierung wäre es möglich auch alle Felder zu übertragen.

Kannst du ein (kurzes) Beispiel zeigen, denn ganz verstehe ich die Aufgabe nicht.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

T
THQ Themenstarter:in
68 Beiträge seit 2011
vor 12 Jahren

Hallo,

uh ein Beispiel ist recht schwierig hier aufzuzeigen. Ich kann jedoch ein einfaches erkläre.

Ich habe eine "Personal" Klasse mit dem üblichen Informationen (Name, Alter, Geb., Straße, etc.).
Das ist sozuagen der erste Teil dieser Klasse. Desweiteren gibt es in dieser Klasse noch Felder die erst später geladen werden soll, wenn man über die Person noch mehr Informationen haben will.

Das ist so zu verstehen, dass die erste Version für kleinere Anzeigen etc. gedacht ist, und die große für das Bearbeiten dieses Mitarbeiters.

Nun habe ich die "kleine" Klasse in meinem Cache geladen, und es kommt nun die Anfrage, dass der Rest der Klasse nachgeladen werden soll. Dies bedeuted ich erhalte die gesamte Klasse vom Server und muss diese nun in die Klasse, welche im Cache schon ist, übertragen.

Den Eintrag aus dem Cache löschen und den neu erhaltenen einfügen, kann ich nicht machen, da auf die kleine Klasse schon evtl. andere Sachen im Programm zeigen könnten.

Ich hoffe ich konnte es recht gut erklären.

mfg thq

D
500 Beiträge seit 2007
vor 12 Jahren

Hi THQ!

Ich wuerde gar nicht erst die Instanz austauschen wollen. Warum denn nicht einfach eine Instanz der Personal Klasse mit Daten auffuellen, wenn diese benoetigt werden?
Verwendest Du einen OR-Mapper fuer die Persistierung?

Gruss,
Moe

T
THQ Themenstarter:in
68 Beiträge seit 2011
vor 12 Jahren

Eine Art auffüllen ist es ja was ich meine. Jedoch schon auf eine bestehende Instanz einer Klasse, wovon ich aber nur den Generischen Typ habe 😃

Einen OR-Mapper benutze ich nicht, da ich nicht direkt mit einem Service verbunden bin.

mfg

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo THQ,

erstmal solltest du klarer zwischen Klasse und Objekt/Instanz trennen. Daten kann man nicht von einer Klasse in die anderen übertragen, sondern nur von einem Objekt in das andere.

Zur eigentlichen Problem: Ich halte es nicht für sinnvoll, dass es zwei Personen-Klassen gibt. Es sollte nur eine Klasse Person geben. Und es sollte pro (natürlicher) Person nur ein Objekt geben. Wenn also Daten nachgeladen werden, sollte das sofort in diesem einen Objekt für die Person erfolgen. Als Nebeneffekt lösen sich alle geschilderten Problem in Luft auf.

herbivore

T
THQ Themenstarter:in
68 Beiträge seit 2011
vor 12 Jahren

Hallo,

also müsste ich dann sozusagen mit zwei Klassen arbeiten.
Einmal mit der "kleinen" Personen Klasse und dann einmal mit der "extended Personen Klasse", welche von der kleinen Personenklasse abgeleitet worden ist.

Damit hätte ich 2 Caches. Einmal für die kleine, wo alle drinne stehen die in Übersichten da sind. Und einmal ein Cache mit den großen Klassen (der Cache würde auch nur gefüllt werden, wenn der komplette Mitarbeiter angefordert wird).

Mit der Strategie, das große Laden wenn ich nur das kleine brauche, würde in einer Übersicht aus z.B. 100 Personen nicht mehr aufgehen. Da man die extend nur bei einem kleinen Bruchtteil benötigt.

mfg thq

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo THQ,

also müsste ich dann sozusagen mit zwei Klassen arbeiten.

nein, ich stehe auf dem Standpunkt, dass es nur eine Klasse geben sollte.

Das steht nicht im Widerspruch dazu, dass man einige Teile erst bei Bedarf nachladen kann. Stichwort: lazy loading.

herbivore

T
THQ Themenstarter:in
68 Beiträge seit 2011
vor 12 Jahren

Es ist jedoch nur so, dass es vorkommen kann, dass jemand eine Übersicht einstellt, das in einer Tabelle zum Navigieren 100 Personen angezeigt werden kann trotzdem Paging etc.
(Je nachdem wie der Benutzer es einstell). Das wäre sozusagen die kleiner Information in der Tabelle. Die vollständig gefüllte Instanz benötige ich erst, wenn der Benutzer eine Person auswählt und diese dann angezeigt wird.

Daher, wieso 100 komplette Datensätze laden, wenn der Benutzer davon vllt. 2 braucht?
In solchem Szenario finde ich dies eine große Verschwendung von Ressourcen. (Speicher wie auch Netzwerk Traffic).

mfg

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

wieso 100 komplette Datensätze laden

es werden beim Lazy Loading nicht die kompletten Datensätze geladen, sondern erstmals nur die wichtigsten Informationen und alle anderen dann erst bei Bedarf.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

2.187 Beiträge seit 2005
vor 12 Jahren

Hallo THQ,

Vielleicht hilf ein kleines Stück Code wie dei eine Person-Klasse aussehen soll:


public class Person
{
  // eine Normales Property, welches immer geladen wird.
  public virtual string Name{get;set;} 

  // eins der "extended" Properties, welches erst bei bedarf geladen wird (LazyLoading)
  private string _Bemerkung;
  public virtual string Bemerkung
  {
    get
    {
       this.NachLaden();
       return this._Bemerkung;
    }
    set
    {
       this.NachLaden();
       this._Bemerkung = value;
    }
  }

  private bool _IsNachgeladen = false;
  private void NachLaden()
  {
    if(!this._IsNachgeladen)
    {
      this._IsNachgeladen = true;
      // alle Zusätzlichen Properties füllen
    }
  }
}

Also noch mal: Es gibt nur eine Person-Klasse. Am Anfang werden nur die einfachen Daten geladen (alle neuen Objekte sind also "kleine" Personen) und erst wenn die weiteren Daten benötigt werden lädt die Instanz selbst automatisch den Rest nach (allso werden alle Objekte zu "erweiterten" Personen, ohne dass man außen irgend was davon wissen müsste oder sich gar das Objekt ändert).

Gruß
Juy Juka

5.742 Beiträge seit 2007
vor 12 Jahren

Wenn man mit einem O/R-Mapper arbeitet, kann man auch die zusätzlichen Infos einfach in eine weitere Klasse auslagern - dann kümmert sich der Mapper um das LazyLoading:


public class Person
{
   public string Name { get; set; }
   public PersonDetails Details { get; set; }
}

public class PersonDetails
{
   public string Bemerkung { get; set; }   
}

Evtl. kann man das im EntityFramework sogar so konfigurieren, dass letztlich alles in einer Tabelle liegt.

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo THQ,

auch wenn ich persönlich kein Fan der *Details-Lösung bin, besteht doch ein wesentlicher Vorteil gegenüber deiner Zwei-Klassen-Lösung: Die eine Klasse repräsentiert die Person, die anderen repräsentiert zusätzliche Informationen zu dieser Person. Eine klare Sache. Wenn dagegen wie - bei deinem ursprünglichen Ansatz - beide Klassen dieselbe Person als ganzes (wenn auch mit unterschiedliche viel Daten) repräsentieren, muss man beim Nachladen die bestehenden Informationen umkopieren, in Listen zwischen den Typen bzw. Objekten umswitchen und hat keine eindeutige 1:1 Zuordnung zwischen Modell und realer Welt.

herbivore

W
955 Beiträge seit 2010
vor 12 Jahren

... Wenn dagegen wie - bei deinem ursprünglichen Ansatz - beide Klassen dieselbe Person als ganzes (wenn auch mit unterschiedliche viel Daten) repräsentieren, muss man beim Nachladen die bestehenden Informationen umkopieren, in Listen zwischen den Typen bzw. Objekten umswitchen und hat keine eindeutige 1:1 Zuordnung zwischen Modell und realer Welt. Hallo,
eine andere Möglichkeit wäre ein virtueller Proxy der das Nachladen steuert. Der Client sieht nur den Proxy der dieselbe Schnittstelle des Modellobjektes implementiert und Anfragen an das Modellobjekt weiterreicht. Wenn Daten noch nicht verfügbar sind kann der Proxy das Nachladen anstoßen. Dann hat man ein sauberes Modellobjekt ohne storage-infos und es muß nichts kopiert werden.

1.820 Beiträge seit 2005
vor 12 Jahren

Hallo!

@witte: Das geht aber schon wieder Richtung OR-Mapper / Persistenz-Schicht. Da würde sich die Frage stellen, ob sich eine Eigenlösung vom Aufwand her rechnet oder lieber eine fertige Lösung herhalten sollte.

Nobody is perfect. I'm sad, i'm not nobody 🙁

W
955 Beiträge seit 2010
vor 12 Jahren

@tom-essen:
Das ist richtig. Er will aber keinen ORM verwenden "weil er mit dem Service nicht direkt verbunden ist". Dann muß er Lazy halt manuell implementieren.