Bauen der Web-App
Kurzüberblick 03
Testanwendung
Sushi für's Hirn
ICM@I3CM
Inverted Classroom Model im Institut für Ingenieurinformatik und computergestützte Mathematik (I3CM)
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Vorbemerkung
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Vorbemerkung
Zu Testzwecken bietet es sich an eine Testanwendung zu erstellen, die mittels der erstellten Klassenbibliothek auf die Datenbank zugreift. So kann der Datenbankzugriff unabhängig vom Webserver getestet werden.
In dieser Präsentation finden Sie einige grundlegende Aufrufe zum Zugriff auf die Datenbank mit Erläuterungen.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Testanwendung
Erstellen der Anwendung
Implementierung der Objektfunktionen
Implementierung der Relationsfunktionen
Implementierung von Abfragen
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Erstellen der Testanwendung
Die Anwendung wird als neues Projekt zur Solution hinzugefügt.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Auswahl der Vorlage
Wählen Sie als Anwendungsform eine Windows Forms App aus und achten dabei auf die korrekte Programmiersprache (C#) und die korrekte Laufzeitumgebung (.NET Framework).
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Benennung
Geben Sie der Anwendung einen sinnvollen Namen.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Verfügbarmachen des EntityFrameWorks
Das EntityFrameWork wurde als Paket nachinstalliert und ist daher im Moment nur für die Klassenbibliothek verfügbar.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Verfügbarmachen des EntityFrameWorks
Das EntityFrameWork wurde als Paket nachinstalliert und ist daher im Moment nur für die Klassenbibliothek verfügbar.
Setzen Sie den Haken auch für die Application und drücken dann die Schaltfläche ‘Install’.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Verfügbarmachen der Klassenbibliothek
Neben dem Zugriff auf die Klassenbibliothek des EntityFrameWorks benötigt unsere Application auch Zugriff auf unsere eigene Klassenbibliothek. Fügen Sie diese über Rechtsclick auf ‘References’ hinzu.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Verfügbarmachen des EntityFrameWorks
Neben dem Zugriff auf die Klassenbibliothek des EntityFrameWorks benötigt unsere Application auch Zugriff auf unsere eigene Klassenbibliothek. Fügen Sie diese über Rechtsclick auf ‘References’ hinzu.
Unter Projects → Solution sollte Ihre Klassenbibliothek aufgeführt sein. Setzen Sie dort einen Haken.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Prüfen der Referenzen
Unter ‘References’ sollte nun beide neuen Referenzen sichtbar sein.
Neue Referenzen
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Zugriff auf die Datenbank
Der Zugriffsweg auf die Datenbank wird über die abgespeicherte Datenbankverknüpfung realisiert. Den spezifischen Connection String lädt die Anwendung aus der .config-Datei.
Diese wird unter App.config abgelegt.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Zugriff auf die Datenbank
Der Zugriffsweg auf die Datenbank wird über die abgespeicherte Datenbankverknüpfung realisiert. Den spezifischen Connection String lädt die Anwendung aus der .config-Datei.
Diese wird unter App.config abgelegt.
Der Connection String, den Sie im vorherigen Abschnitt in der App.config der Klassenbibliothek abgelegt haben, muss daher in die App.config der Anwendung kopiert werden.
Beim Compilieren wird die App.config unter dem Namen der Anwendung mit ins Zielverzeichnis kopiert, die Konfiguration kann somit auf dem Zielsystem angepasst werden.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Textausgabe aktivieren
Der Anwendungstyp “WinForms Application” zeigt nur ein Formular als Hauptfenster der Anwendung an.
Bei einer Testanwenung ist es aber sinnvoll, wenn daneben noch eine Textausgabe möglich ist. Deshalb soll die Anwendung auch eine Konsolenausgabe haben.
Wählen Sie dazu im Kontextmenü des Projektes die Eigenschaften aus.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Textausgabe aktivieren
Der Anwendungstyp “WinForms Application” zeigt nur ein Formular als Hauptfenster der Anwendung an.
Bei einer Testanwenung ist es aber sinnvoll, wenn daneben noch eine Textausgabe möglich ist. Deshalb soll die Anwendung auch eine Konsolenausgabe haben.
Wählen Sie dazu im Kontextmenü des Projektes die Eigenschaften aus und stellen dann den Output type auf ‘Console Application’ um.
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Testanwendung
Erstellen der Anwendung
Implementierung der Objektfunktionen
Implementierung der Relationsfunktionen
Implementierung von Abfragen
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objektfunktionen
Create
Update
Delete
Objektlebens-�zyklus
Benutzer-
aktione
List
Select
Edit
Action
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
ConfigForm
Muss importiert werden
TODO
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Zum Erstellen und Einspeichern eines neuen Objektes wird zunächst ein einfaches Objekt im Speicher erzeugt.
try
{
User user = new User()
{
Name = "Otto",
Familyname = "Mustermann",
Street = "Musterstraße",
PostCode = "12345",
City = "Ingolstadt"
};
if (ConfigForm.showDialog("Neuer User",
user, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())� {
container.Users.Add(user);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Zum Erstellen und Einspeichern eines neuen Objektes wird zunächst ein einfaches Objekt im Speicher erzeugt.
Dieses wird dem Anwender dann zum Ediztieren angeboten (ConfigForm bietet dazu eine einfache Möglichkeit).
try
{
User user = new User()
{
Name = "Otto",
Familyname = "Mustermann",
Street = "Musterstraße",
PostCode = "12345",
City = "Ingolstadt"
};
if (ConfigForm.showDialog("Neuer User",
user, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())� {
container.Users.Add(user);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Zum Erstellen und Einspeichern eines neuen Objektes wird zunächst ein einfaches Objekt im Speicher erzeugt.
Dieses wird dem Anwender dann zum Ediztieren angeboten (ConfigForm bietet dazu eine einfache Möglichkeit).
Dann beschafft man sich einen modell-�spezifischen Datenbankadapter, fügt das neue Objekt in das entsprechende DBSet ein und speichert die Änderungen.
try
{
User user = new User()
{
Name = "Otto",
Familyname = "Mustermann",
Street = "Musterstraße",
PostCode = "12345",
City = "Ingolstadt"
};
if (ConfigForm.showDialog("Neuer User",
user, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())� {
container.Users.Add(user);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Freigabe des Datenbankadapters
Da der Datenbankadapter neben dem eigentlichen Arbeitsspeicher innerhalb der ausgeführten Anwendung auch externe Ressourcen nutzt, implementiert er das Interface IDisposable.
Dieses Interface gehört zu den Basis-�Elementen von .NET und wird von allen Klassen implementiert, die externe Ressourcen nutzen, z.B. Dateizugriff, Druckerzugriff.
C# stellt mit using einen Ausführungsblock bereit, der dem Rechnung trägt. Wie bei einer Schleife, steht das Objekt, welches innerhalb der Klammern instanziiert wurde, innerhalb des Blockes zur Verfügung. Am Endes des Blockes werden alle externen Ressourcen freigegeben.
try
{
User user = new User()
{
Name = "Otto",
Familyname = "Mustermann",
Street = "Musterstraße",
PostCode = "12345",
City = "Ingolstadt"
};
if (ConfigForm.showDialog("Neuer User",
user, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())� {
container.Users.Add(user);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Exception Handling
Beim Zugriff auf die Datenbank kann einiges schief gehen. Dann werden entsprechende Exceptions geworfen. In diesem Beispiel werden diese alle von einer zentralen Methode behandelt, diese bereitet die Daten so auf, dass sinnvolle Informationen angezeigt werden.
Übernehmen Sie diese Funktion in Ihre eigene Anwendung.
try
{
User user = new User()
{
Name = "Otto",
Familyname = "Mustermann",
Street = "Musterstraße",
PostCode = "12345",
City = "Ingolstadt"
};
if (ConfigForm.showDialog("Neuer User",
user, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())� {
container.Users.Add(user);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Zum Editieren eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
if (ConfigForm.showDialog("Kundenänderung",
user, true) != DialogResult.OK)
return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Zum Editieren eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Das Editieren erfolgt wieder über ConfigForm.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
if (ConfigForm.showDialog("Kundenänderung",
user, true) != DialogResult.OK)
return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Zum Editieren eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Das Editieren erfolgt wieder über ConfigForm.
Bestätigt der Anwender mit ‘OK’, dann werden die Änderungen gespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
if (ConfigForm.showDialog("Kundenänderung",
user, true) != DialogResult.OK)
return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Bestätigt der Anwender mit ‘OK’, dann werden die Änderungen gespeichert.
Beachten Sie, dass das geänderte Objekt dem DBSet nicht hinzugefügt werden muss, da es bereits aus diesem entnommen wurde.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
if (ConfigForm.showDialog("Kundenänderung",
user, true) != DialogResult.OK)
return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt löschen
Zum Löschen eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
container.Users.Remove(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt löschen
Zum Löschen eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Wählt der Anwender ein Objekt aus, dann wird es aus dem entsprechenden DBSet entfernt. Die Änderungen müssen dann wieder abgespeichert werden.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Kundenauswahl",
"Kunden auswählen",
null,
container.Users);
if (user == null) return;
container.Users.Remove(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Zum Erstellen und Einspeichern eines neuen Objektes wird zunächst ein einfaches Objekt im Speicher erzeugt.
Dieses wird dem Anwender dann zum Ediztieren angeboten (ConfigForm bietet dazu eine einfache Möglichkeit).
Dann beschafft man sich einen modell-�spezifischen Datenbankadapter, fügt das neue Objekt in das entsprechende DBSet ein und speichert die Änderungen.
try
{
Work work = new Work()
{
Titel = "Titel",
Author = "Ernest Hemmingway",
Verlag = "dtv",
Standort = "K/R13"
};
if (ConfigForm.showDialog("Neues Werk",
work, true) == DialogResult.OK)
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
container.Works.Add(work);
container.SaveChanges();
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Zum Editieren eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Das Editieren erfolgt wieder über ConfigForm.
Bestätigt der Anwender mit ‘OK’, dann werden die Änderungen gespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
if (ConfigForm.showDialog("Werkänderung",
work, true) != DialogResult.OK) return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt löschen
Zum Löschen eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Wählt der Anwender ein Objekt aus, dann wird es aus dem entsprechenden DBSet entfernt. Die Änderungen müssen dann wieder abgespeichert werden.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
container.Works.Remove(work);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Vor dem Erstellen und Einspeichern eines neuen Objektes vom Type Medium muss zunächst das Werk ausgewählt werden. Die Auswahl wird über den Mechanismus in SelectDialog realisiert. Diesem werden wieder alle vorhandenen Werke als Auswahlmöglichkeiten übergeben.
Erst dann wird ein einfaches Objekt im Speicher erzeugt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk für neues Medium auswählen.",
null, container.Works);
if (work == null) return;
Media media = new Media()
{
Number = Guid.NewGuid().ToString()
.Replace("-", string.Empty)
.Substring(0, 6)
};
media.Work = work;
if (ConfigForm.showDialog("Neues Medium",
media, true) == DialogResult.OK)
{
container.Media.Add(media);
container.SaveChanges();
}
}
}
catch (Exception ex) { handle(ex); }
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt erstellen
Dieses neue Objekt wird dem Anwender dann zum Editieren angeboten (ConfigForm bietet dazu eine einfache Möglichkeit).
Dann fügt man das neue Objekt in das entsprechende DBSet des modell- spezifischen Datenbankadapter ein und speichert die Änderungen.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk für neues Medium auswählen.",
null, container.Works);
if (work == null) return;
Media media = new Media()
{
Number = Guid.NewGuid().ToString()
.Replace("-", string.Empty)
.Substring(0, 6)
};
media.Work = work;
if (ConfigForm.showDialog("Neues Medium",
media, true) == DialogResult.OK)
{
container.Media.Add(media);
container.SaveChanges();
}
}
}
catch (Exception ex) { handle(ex); }
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt editieren
Zum Editieren eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Das Editieren erfolgt wieder über ConfigForm.
Bestätigt der Anwender mit ‘OK’, dann werden die Änderungen gespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Media media = SelectDialog<Media>.show(
"Medienauswahl",
"Medium auswählen",
null,
container.Media);
if (media == null) return;
if (ConfigForm.showDialog("Werkänderung",
media, true) != DialogResult.OK) return;
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Objekt löschen
Zum Löschen eines Objektes muss dieses ausgewählt werden. Der Zugriff auf die vorhandenen Objekte erfolgt wieder über das entsprechende DBSet.
SelectDialog stellt eine Funktion zur Auswahl von Objekten zur Verfügung, als Liste der möglichen Auswahlelemente wird hier direkt das DBSet übergeben.
Wählt der Anwender ein Objekt aus, dann wird es aus dem entsprechenden DBSet entfernt. Die Änderungen müssen dann wieder abgespeichert werden.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Media media = SelectDialog<Media>.show(
"Medienauswahl",
"Medium auswählen",
null,
container.Media);
if (media == null) return;
container.Media.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Testanwendung
Erstellen der Anwendung
Implementierung der Objektfunktionen
Implementierung der Relationsfunktionen
Implementierung von Abfragen
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Relationsfunktionen
Create
Update
Delete
Relations-�lebenszyklus
Benutzer-
aktione
List
Select
Edit
Action
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
Zur Bestellung muss der Anwender ein Werk auswählen.
Technisch muss dann eine Bestellt-Relation zwischen dem Werk und dem Anwender erstellt werden.
Ideal wäre es also, wenn die Aktion ‘Bestellen’ aus einer Auflistung von Werken heraus angestoßen werden könnte und der Datensatz des Anwender aus dem Kontext ermittelt würde.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Werk aus der Liste aller Werke ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Werk aus der Liste aller Werke ausgewählt.
Das Erstellen der Relation erfolgt durch das Einfügen des ausgewählten Werkes in die Bestellliste des Ausgewählten Anwenders.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Werk aus der Liste aller Werke ausgewählt.
Das Erstellen der Relation erfolgt durch das Einfügen des ausgewählten Werkes in die Bestellliste des Ausgewählten Anwenders.
Anschließen wird wieder abgespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellen
Anschließen wird wieder abgespeichert.
Beachten Sie, dass das die beiden Objekte dem DBSet nicht hinzugefügt werden muss, da diese bereits daraus entnommen wurden.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk zur Bestellung auswählen.",
null,
container.Works);
if (work == null) return;
work.Orderer.Add(user);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
Zum Ausleihen muss der Anwender ein Medium auswählen.
Technisch muss dann eine Leiht-Relation zwischen dem Medium und dem Anwender erstellt werden.
Ideal wäre es also, wenn die Aktion ‘Ausleihen’ aus einer Auflistung von Medien heraus angestoßen werden könnte und der Datensatz des Anwender aus dem Kontext ermittelt würde.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Werk aus der Liste aller Werke, die nicht ausgeliehen sind ausgewählt. Diese Liste wird mittels LINQ aus dem DBSet der Medien ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
Das Erstellen der Relation erfolgt durch das Einfügen des ausgewählten Mediums in die Ausleihliste des ausgewählten Anwenders.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
Das Erstellen der Relation erfolgt durch das Einfügen des ausgewählten Mediums in die Ausleihliste des ausgewählten Anwenders.
Als nächstes wird das auf dem Medium enthaltene Werk aus der Bestellliste es Anwenders entfernt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausleihen
Das Erstellen der Relation erfolgt durch das Einfügen des ausgewählten Mediums in die Ausleihliste des ausgewählten Anwenders.
Als nächstes wird das auf dem Medium enthaltene Werk aus der Bestellliste es Anwenders entfernt.
Abschließend werden die Änderungen abgespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
var medias = (from m in container.Media
where m.User == null
select m);
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
medias);
if (media == null) return;
user.Loans.Add(media);
user.Orders.Remove(media.Work);
container.SaveChanges();
}
}
catch (Exception ex){handle(ex);}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Rückgabe
Zur Rückgabe muss der Anwender ein Medium auswählen.
Technisch muss dann die Leiht-Relation zwischen dem Medium und dem Anwender gelöscht werden.
Ideal wäre es also, wenn die Aktion ‘Ausleihen’ aus einer Auflistung von Medien, die der Anwender ausgeliehen hat, heraus angestoßen werden könnte und der Datensatz des Anwender aus dem Kontext ermittelt würde.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
if (media == null) return;
user.Loans.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Rückgabe
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
if (media == null) return;
user.Loans.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Rückgabe
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Medium aus der Liste, der vom ausgewählten Anwender ausgeliehenen Medien ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
if (media == null) return;
user.Loans.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Rückgabe
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Medium aus der Liste, der vom ausgewählten Anwender ausgeliehenen Medien ausgewählt.
Dann wird das ausgewählte Medium aus der Ausleihliste des Anwenders entfernt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
if (media == null) return;
user.Loans.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Rückgabe
In der Test-Anwendung wird zunächst über den bekannten SelectDialog-Mechanismus ein Anwender aus der Liste aller Anwender ausgewählt.
Anschließend wird auf die gleiche Weise ein Medium aus der Liste, der vom ausgewählten Anwender ausgeliehenen Medien ausgewählt.
Dann wird das ausgewählte Medium aus der Ausleihliste des Anwenders entfernt.
Abschließend werden die Änderungen abgespeichert.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
if (media == null) return;
user.Loans.Remove(media);
container.SaveChanges();
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Testanwendung
Erstellen der Anwendung
Implementierung der Objektfunktionen
Implementierung der Relationsfunktionen
Implementierung von Abfragen
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Infolauf
Als Beispiel für eine Abfrage sei hier ein Infolauf dargestellt. Ziel ist es für alle vorbestellten Werke, für die ein nicht entliehenes Medium existiert, eine Nachricht zu erstellen, in der die Vorbesteller aufgelistet sind.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
foreach (Work work in
(from w in container.Works
where w.Orderer.Count() > 0
&& w.Media.Count(m => m.User == null) > 0
select w))
{
MessageBox.Show(
$"Das bestellte Werk{Environment.NewLine}" +
$"{work}{Environment.NewLine}" +
$"ist verfügbar.{Environment.NewLine}" +
$"Besteller:{Environment.NewLine}" +
string.Join(Environment.NewLine,
work.Orderer.Select(u => u.ToString())),
@"Bestelltes Werk verfügbar");
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Infolauf
Als Beispiel für eine Abfrage sei hier ein Infolauf dargestellt. Ziel ist es für alle vorbestellten Werke, für die ein nicht entliehenes Medium existiert, eine Nachricht zu erstellen, in der die Vorbesteller aufgelistet sind.
Dazu wird diese Werke zunächst mittels einer LINQ-Abfrage ermittelt. Ausgewählt werden alle Werke, bei denen die Vorbestellerliste nicht leer ist (Count() > 0) und bei denen in der Medienliste mindestens ein (Count() > 0) unausgeliehenes Medium (m.User == null) enthalten ist.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
foreach (Work work in
(from w in container.Works
where w.Orderer.Count() > 0
&& w.Media.Count(m => m.User == null) > 0
select w))
{
MessageBox.Show(
$"Das bestellte Werk{Environment.NewLine}" +
$"{work}{Environment.NewLine}" +
$"ist verfügbar.{Environment.NewLine}" +
$"Besteller:{Environment.NewLine}" +
string.Join(Environment.NewLine,
work.Orderer.Select(u => u.ToString())),
@"Bestelltes Werk verfügbar");
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Infolauf
Dazu wird diese Werke zunächst mittels einer LINQ-Abfrage ermittelt. Ausgewählt werden alle Werke, bei denen die Vorbestellerliste nicht leer ist (Count() > 0) und bei denen in der Medienliste mindestens ein (Count() > 0) unausgeliehenes Medium (m.User == null) enthalten ist.
Für alle so ausgewählten Werk wird dann eine Nachricht erzeugt und per MessageBox angezeigt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
foreach (Work work in
(from w in container.Works
where w.Orderer.Count() > 0
&& w.Media.Count(m => m.User == null) > 0
select w))
{
MessageBox.Show(
$"Das bestellte Werk{Environment.NewLine}" +
$"{work}{Environment.NewLine}" +
$"ist verfügbar.{Environment.NewLine}" +
$"Besteller:{Environment.NewLine}" +
string.Join(Environment.NewLine,
work.Orderer.Select(u => u.ToString())),
@"Bestelltes Werk verfügbar");
}
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellung von Kunden
Eine Auflistung von Bestellungen eines Kunden wäre in einer klassischen Datenbankanwendung als Abfrage zu formulieren. Im EntityFrameWork übernimmt dies die Abstraktionsschicht für uns.
Nach der Auswahl eines Anwenders aus der Liste aller Anwender ...
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
SelectDialog<Work>.show(
"Bestellungen",
$"Bestellungen von {user}",
null,
user.Orders);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellung von Kunden
Eine Auflistung von Bestellungen eines Kunden wäre in einer klassischen Datenbankanwendung als Abfrage zu formulieren. Im EntityFrameWork übernimmt dies die Abstraktionsschicht für uns.
Nach der Auswahl eines Anwenders aus der Liste aller Anwender, steht uns die Liste seiner Vorbestellungen in dessen Vorbestellungsliste zur Verfügung.
Der Aufruf von SelectDialog.show() dient nur dazu diese Liste anzuzeigen.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Bestellerauswahl",
"Besteller auswählen",
null,
container.Users);
if (user == null) return;
SelectDialog<Work>.show(
"Bestellungen",
$"Bestellungen von {user}",
null,
user.Orders);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausgeliehen von Kunden
Eine Auflistung von durch einen Kunden ausgeliehenen Medien erfolgt analog.
Nach der Auswahl eines Anwenders aus der Liste aller Anwender, ...
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausgeliehen von Kunden
Eine Auflistung von durch einen Kunden ausgeliehenen Medien erfolgt analog.
Nach der Auswahl eines Anwenders aus der Liste aller Anwender, steht uns die Liste seiner Ausgeliehenen Medien in dessen Ausleihliste zur Verfügung.
Der Aufruf von SelectDialog.show() dient nur dazu diese Liste anzuzeigen.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
User user = SelectDialog<User>.show(
"Ausleiherwahl",
"Ausleiher auswählen",
null,
container.Users);
if (user == null) return;
Media media = SelectDialog<Media>.show(
"Medium",
"Medium zum Leihen auswählen.",
null,
user.Loans);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellungen für Werke
Eine Auflistung von Vorbestellungen für ein Werk erfolgt analog.
Nach der Auswahl eines Werkes aus der Liste aller Werke ...
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
SelectDialog<User>.show(
"Bestellungen",
$"Bestellungen für {work}",
null,
work.Orderer);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Bestellungen für Werke
Eine Auflistung von Vorbestellungen für ein Werk erfolgt analog.
Nach der Auswahl eines Werkes aus der Liste aller Werke, steht uns die Liste seiner Vorbesteller dessen Vorbestellerliste zur Verfügung.
Der Aufruf von SelectDialog.show() dient nur dazu diese Liste anzuzeigen.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
SelectDialog<User>.show(
"Bestellungen",
$"Bestellungen für {work}",
null,
work.Orderer);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausgeliehene Werke
Eine Auflistung aller User, die ein Werk ausgeliehen haben, erfolgt durch eine einfache LINQ-Abfrage.
Nach der Auswahl eines Werkes aus der Liste aller Werke...
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
var users = (
from m in work.Media
where m.User != null
select m.User
);
SelectDialog<User>.show(
"Ausgeliehen Werke",
$"Ausleiher für {work}",
null,
users);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausgeliehene Werke
Eine Auflistung aller User, die ein Werk ausgeliehen haben, erfolgt durch eine einfache LINQ-Abfrage.
Nach der Auswahl eines Werkes aus der Liste aller Werke, können einfach alle Medien dieses Werkes ermittelt werdem, die verliehen sind. Für alle diese Medien wird jeweils der Entleiher ausgewählt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
var users = (
from m in work.Media
where m.User != null
select m.User
);
SelectDialog<User>.show(
"Ausgeliehen Werke",
$"Ausleiher für {work}",
null,
users);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Ausgeliehene Werke
Eine Auflistung aller User, die ein Werk ausgeliehen haben, erfolgt durch eine einfache LINQ-Abfrage.
Nach der Auswahl eines Werkes aus der Liste aller Werke, können einfach alle Medien dieses Werkes ermittelt werdem, die verliehen sind. Für alle diese Medien wird jeweils der Entleiher ausgewählt.
Diese Liste der Entleiher wird im Beispiel mittels SelectDialog.show() dargestellt.
try
{
using (BibliothekModelContainer container =
new BibliothekModelContainer())
{
Work work = SelectDialog<Work>.show(
"Werkauswahl",
"Werk auswählen",
null,
container.Works);
if (work == null) return;
var users = (
from m in work.Media
where m.User != null
select m.User
);
SelectDialog<User>.show(
"Ausgeliehen Werke",
$"Ausleiher für {work}",
null,
users);
}
}
catch (Exception ex)
{
handle(ex);
}
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen
Prof. Dr.-Ing. Jörn Schlingensiepen
https://lehre.schlingensiepen.com
Cliparts aus der Open Clip Art Library
Sushi für's Hirn
ICM@I3CM
Inverted Classroom Model im Institut für Ingenieurinformatik und computergestützte Mathematik (I3CM)
ICM@I3CM
Prof. Dr.-Ing. Jörn Schlingensiepen