Eine Schlüsseltabelle kann bei der Modellierung als historisierte Schlüsseltabelle markiert werden. In einem solchen Fall enthält die Tabelle zwei spezielle Felder, die im Allgemeinen als HIST-BEG-D0
und HIST-ZST-K
benannt sind. In der Spalte HIST-BEG-D0
wird das früheste Datum angegeben, ab wann der Eintrag in der Schlüsseltabelle zu berücksichtigen ist. Die Spalte HIST-ZST-K
kann folgende Werte aufweisen:
Für eine generierte Schlüsseltabelle hat das für die Benutzung mit LINQ zunächst keine Auswirkung. Die Funktionalität der Historisierung muss bei der Benutzung von LINQ anwendungsseitig berücksichtigt werden.
Bei der Benutzung von der Methode Contains
wird dafür gesorgt, dass die Suche mit dem neuesten Eintrag für das aktuelle Datum ausgeführt wird. Die Methode Contains
erhält außerdem eine weitere Ausprägung, mit der explizit ein Sichtdatum für die Suche nach einem passenden Eintrag in der Schlüsseltabelle angegeben werden kann.
Es werden nur Eintrage mit eine aktive Historienkennzeichnung berücksichtigt1).
Auch für die Methode GetOrDefault
2) ist eine weitere Ausprägung vorhanden, mit der explizit ein Sichtdatum für die Suche nach einem passenden Eintrag in der Schlüsseltabelle angegeben werden kann.
Bei der Benutzung mit Indexer wird von der generierten Schlüsseltabelle dafür gesorgt, dass der Eintrag mit dem neuesten Datum in HistBegD0
geliefert wird. Außerdem steht (wie bei Contains
) eine weitere Form des Indexers zur Verfügung, bei der das Sichtdatum explizit angegeben werden kann. Wenn kein Sichtdatum angegeben wurde, wird das aktuelle Datum3) als Sichtdatum benutzt. Allerdings wird auch davon ausgegangen, dass normalerweise für den gefundenen Eintrag eine aktive Historienkennzeichnung erwartet wird. Ist das nicht der Fall, wird eine Ausnahme vom Typ TeamWiSE.Runtime.Reftab.StateUnexpectedException
aufgeworfen. Die Ausnahme hat eine Eigenschaft State
, der den tatsächlichen Wert der Historisierungskennzeichnung beinhaltet. Die Eigenschaft State
ist vom Typ HistZstEnum
und weist neben den oben aufgelisteten Werten auch ein Member Unknown
auf.
Bei historisierten Schlüsseltabellen ist neben der Methode Contains
auch eine Methode State
verfügbar. Um das Aufwerfen einer Ausnahme zu vermeiden, kann man in betroffenen Fällen vorher die Methode State
an der Schlüsseltabelle nutzen, um sicherzustellen, dass zu den gegebenen Daten einen aktiven Eintrag auffindbar ist4).
switch (tab.State(kExkZw)) { case HistZstEnum.Unknown: Program.Log("no value found for {0}", kExkZw); break; case HistZstEnum.Aktiv: break; default: Program.Log("state {1} for {0} not marked as active", kExkZw, tab.State(kExkZw)); break; }
Es stehen für den einfacheren Zugriff auf zustandsbasierte Einträge folgende Listen zur Verfügung:
public IEnumerable<T> Bekannt(bool all = false) public IEnumerable<T> Bekannt(DateTime SichtDatum, bool all = false) public IEnumerable<T> Aktiv(bool all = false) public IEnumerable<T> Aktiv(DateTime SichtDatum, bool all = false) public IEnumerable<T> NichtAktiv(bool all = false) public IEnumerable<T> NichtAktiv(DateTime SichtDatum, bool all = false)
Dabei liefern die Bekannt
-Mathoden5) alle Einträge, die Aktiv()
-Methoden immer die Einträge, die den Zustand HistZstEnum.Aktiv
haben und die NichtAktiv()
-Methoden liefern die Einträge, die einen anderen als HistZstEnum.Aktiv
haben, also bspw. auch HistZstEnum.Abgelehnt
oder HistZstEnum.Storniert
. Es werden nur die Einträge berücksichtigt, dessen HistBegD0
kleiner oder gleich zum SichtDatum
bzw. das aktuelle Datum sind. Nur wenn das optionale Argument all
mit dem Wert true
übergeben wird, werden alle Treffer geliefert, sonst nur die zum jeweiligen Sichtdatum
aktuellsten.
Gegeben sei folgende Liste mit folgenden Einträgen für einen bestimmten Schlüsselwert (K.1
):
Key | HistBegDo | HistZstK |
---|---|---|
K.1 | 01.01.1967 | 1 |
K.1 | 01.10.1971 | 1 |
K.1 | 01.01.1993 | 2 |
K.1 | 01.07.1997 | 1 |
K.1 | 01.01.2013 | 1 |
Dann liefert tab.Aktiv()
den Eintrag für 01.01.2013
. Dafür liefert tab.Aktiv(true)
alle bis auf den Eintrag für 01.01.1993
, weil dieser als einziger nicht als aktiv markiert ist. Der Aufruf tab.Aktiv(new DateTime(1994, 1, 1))
liefert den Eintrag für keine Einträge, e.g. eine leere Liste6). Der Aufruf 01.10.1971
als aktuellstertab.Aktiv(new DateTime(1994, 1, 1), true)
liefert die Einträge 01.01.1967
und 01.10.1971
.
Für komplexere Fälle gibt es noch folgende Methoden:
public IEnumerable<T> WhereStateIn(IEnumerable<HistZstEnum> states, bool all = false) public IEnumerable<T> WhereStateIn(IEnumerable<HistZstEnum> states, DateTime SichtDatum, bool all = false) public IEnumerable<T> WhereStateNotIn(IEnumerable<HistZstEnum> states, bool all = false) public IEnumerable<T> WhereStateNotIn(IEnumerable<HistZstEnum> states, DateTime SichtDatum, bool all = false)
Damit wäre bspw. folgendes möglich:
foreach (var row in table.WhereStateNotIn(new[] { HistZstEnum.Abgelehnt, HistZstEnum.Ruhend })) { ... }
State
oder Contains
und einer anschließenden Nutzung des Indexers
keine erneute Suche stattfindet, sondern - wenn passend - zeitsparend ohne Suche direkt der gleiche Eintrag geliefert wird.