DataGrid – IQueryable & Mapping
Echtes EF Core + SQLite + AutoMapper Szenario: DbContext.Mitarbeiter wird per
ProjectTo<MitarbeiterDto>() gemappt. Kein .ToList() vor der Übergabe –
das DataGrid bekommt ein IQueryable<MitarbeiterDto> direkt aus der DB.
2.000.000 Datensätze, Sortierung und Paging laufen über EF Core / SQLite.
IQueryable mit Paging (2.000.000 Einträge, PageSize 20)
QueryableItems – Sortierung + Paging über IQueryable
Nr. | Name | Abteilung | Eintrittsdatum | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | 08.04.2013 | 2.973,00 |
| 2 | Wagner Sabine | Marketing | 15.07.2014 | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | 22.10.2015 | 3.319,00 |
| 4 | Fischer Laura | HR | 01.01.2016 | 3.492,00 |
| 5 | Weber Markus | Finanzen | 08.04.2017 | 3.665,00 |
| 6 | Becker Julia | Einkauf | 15.07.2018 | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | 22.10.2019 | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | 01.01.2020 | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | 08.04.2021 | 3.307,00 |
| 10 | Richter Claudia | Marketing | 15.07.2022 | 3.480,00 |
| 11 | Klein Martin | Vertrieb | 22.10.2023 | 3.653,00 |
| 12 | Wolf Sandra | HR | 01.01.2012 | 3.826,00 |
| 13 | Schröder Michael | Finanzen | 08.04.2013 | 3.999,00 |
| 14 | Neumann Katharina | Einkauf | 15.07.2014 | 3.122,00 |
| 15 | Schwarz Frank | Produktion | 22.10.2015 | 3.295,00 |
| 16 | Zimmermann Monika | IT-Betrieb | 01.01.2016 | 3.468,00 |
| 17 | Braun Bernd | Entwicklung | 08.04.2017 | 3.641,00 |
| 18 | Krüger Christine | Marketing | 15.07.2018 | 3.814,00 |
| 19 | Hofmann Jürgen | Vertrieb | 22.10.2019 | 3.987,00 |
| 20 | Hartmann Nicole | HR | 01.01.2020 | 4.160,00 |
Sub-Entity-Mapping: e.Beschaeftigung.Name → Statusname
Statusname direkt aus verschachtelter Entity gemappt – Badge per CellTemplate
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
Gefilterte IQueryable-Teilmenge (nur Abteilung "Entwicklung")
Zeigt wie ein .Where() vor der Übergabe funktioniert – simuliert Server-seitiges Filtern
Nr. | Name | Gehalt (€) |
|---|---|---|
| 1 | Müller Andreas | 2.973,00 |
| 9 | Bauer Peter | 3.307,00 |
| 17 | Braun Bernd | 3.641,00 |
| 25 | Krause Hans | 3.975,00 |
| 33 | Schneider Thomas | 4.309,00 |
| 41 | Klein Martin | 4.643,00 |
| 49 | Hofmann Jürgen | 3.927,00 |
| 57 | Lehmann Klaus | 4.261,00 |
| 65 | Weber Markus | 4.595,00 |
| 73 | Schröder Michael | 4.929,00 |
Suchperformance – 2.000.000 Einträge (voller Datensatz)
Suche läuft direkt über IQueryable auf dem vollständigen Datensatz – kein .Take()
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
Suchperformance – 200.000 Einträge (.Take(200_000))
Suche läuft direkt über IQueryable auf 200.000 Datensätzen
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
Suchperformance – 20.000 Einträge (.Take(20_000))
Suche läuft direkt über IQueryable auf 20.000 Datensätzen
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
Suchperformance – 2.000 Einträge (.Take(2_000))
Suche läuft direkt über IQueryable auf 2.000 Datensätzen
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
Suchperformance – 200 Einträge (.Take(200))
Suche läuft direkt über IQueryable auf nur 200 Datensätzen – Referenzwert für minimale Last
Nr. | Name | Abteilung | Status | Gehalt (€) |
|---|---|---|---|---|
| 1 | Müller Andreas | Entwicklung | Aktiv | 2.973,00 |
| 2 | Wagner Sabine | Marketing | Elternzeit | 3.146,00 |
| 3 | Schneider Thomas | Vertrieb | Krank | 3.319,00 |
| 4 | Fischer Laura | HR | Probezeit | 3.492,00 |
| 5 | Weber Markus | Finanzen | Gekündigt | 3.665,00 |
| 6 | Becker Julia | Einkauf | Aktiv | 3.838,00 |
| 7 | Hoffmann Stefan | Produktion | Elternzeit | 2.961,00 |
| 8 | Koch Anna | IT-Betrieb | Krank | 3.134,00 |
| 9 | Bauer Peter | Entwicklung | Probezeit | 3.307,00 |
| 10 | Richter Claudia | Marketing | Gekündigt | 3.480,00 |
SKILL.md – Datagrid
---
name: DataGrid
description: Onesown Blazor Komponente DataGrid (DataGrid). Verwende diesen Skill wenn du die DataGrid-Komponente verwenden, konfigurieren oder debuggen moechtest.
---
# DataGrid
**Namespace:** `Onesown.Blazor.Components`
**Kategorie:** DataGrid
**Basisklasse:** `OoComponentBase`
**Generisch:** Ja (`DataGrid<TItem>` o.ae.)
Generisches, vollständig serverseitig-kompatibles DataGrid für tabellarische Daten. Unterstützt Spalten-Definition per DataGridColumn-Kindkomponenten, Sortierung (clientseitig und serverseitig), Paging, Freitext-Suche, Spalten-Filter, Einzel- und Mehrfach-Selektion, State-Persistenz via SessionStorage und fixierte (frozen) Spalten.
**Live-Demo:** https://components.schini.com/demo/datagrid
## Parameter
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
| ``Items`` | ``IEnumerable<TItem>`` | | Datenquelle als In-Memory-Liste. Bei gleichzeitiger Angabe von QueryableItems wird QueryableItems bevorzugt. |
| ``QueryableItems`` | ``IQueryable<TItem>`` | | Datenquelle als IQueryable für serverseitige Sortierung und Filterung. Hat Vorrang vor Items. |
| ``EmptyText`` | ``string`` | ``"Keine Daten vorhanden."`` | Anzeigetext wenn die Datenquelle leer ist. Standard: "Keine Daten vorhanden." |
| ``IsBusy`` | ``bool`` | | Zeigt einen Lade-Indikator über der Tabelle und blendet den Inhalt aus, solange true. |
| ``ShowGridLines`` | ``bool`` | ``true`` | Zeigt Rasterlinien zwischen allen Zellen. Standard: true. |
| ``Striped`` | ``bool`` | ``true`` | Hebt jede zweite Zeile farblich hervor (Zebra-Streifen) für bessere Lesbarkeit. Standard: true. |
| ``Hover`` | ``bool`` | ``true`` | Hebt die Zeile unter dem Mauszeiger visuell hervor. Standard: true. |
| ``MaxHeight`` | ``string`` | | Begrenzt die Höhe des Tabellenbereichs (z. B. "400px" oder "60vh"). Wenn gesetzt, wird der Grid-Bereich scrollbar und der Tabellen-Header bleibt beim Scrollen oben fixiert (sticky). |
| ``Columns`` | ``RenderFragment`` | | RenderFragment für die Spalten-Definitionen. Befüllt durch untergeordnete DataGridColumn-Komponenten. |
| ``Filterable`` | ``bool`` | ``false`` | Aktiviert Spalten-Filter-Eingaben in der Header-Zeile für alle filterbaren Spalten. Standard: false. |
| ``ToolbarContent`` | ``RenderFragment`` | | Optionaler Inhalt der rechts über der Tabelle eingeblendet wird (z. B. Export-Buttons oder Aktions-Icons). Wird nur gerendert wenn gesetzt. |
| ``ExportFileName`` | ``string`` | ``"export"`` | Dateiname ohne Erweiterung für den CSV-Download via Export-Button. Standard: "export". |
| ``OnSortChanged`` | ``EventCallback<SortChangedEventArgs<TItem>>`` | | Wird ausgelöst wenn der Nutzer eine Spalten-Überschrift zum Sortieren anklickt. Liefert Property (Spaltenname) und Direction für eigene serverseitige Sortierlogik. |
| ``SearchText`` | ``string`` | | Freitext-Suchwert von außen. Jede Änderung löst automatisch eine neue Abfrage aus und setzt auf Seite 1 zurück. Unterstützt @bind-SearchText. |
| ``SearchTextChanged`` | ``EventCallback<string>`` | | EventCallback für @bind-SearchText. |
| ``OnSearchStarted`` | ``EventCallback`` | | Wird unmittelbar vor dem Start einer neuen Abfrage ausgelöst (z. B. um einen globalen LoadingBar einzublenden). |
| ``OnSearchCompleted`` | ``EventCallback`` | | Wird nach Abschluss einer Abfrage ausgelöst (z. B. um einen globalen LoadingBar auszublenden). |
| ``Page`` | ``int`` | ``1`` | Aktuell angezeigte Seite (1-basiert). Unterstützt @bind-Page für externe Steuerung. Standard: 1. |
| ``PageChanged`` | ``EventCallback<int>`` | | EventCallback für @bind-Page. |
| ``PageSize`` | ``int`` | ``20`` | Anzahl der Einträge pro Seite. Standard: 20. |
| ``PageSizeChanged`` | ``EventCallback<int>`` | | EventCallback für @bind-PageSize. |
| ``PageSizeOptions`` | ``int[]`` | ``new[] { 10, 20, 50, 100 }`` | Auswahlmöglichkeiten für die Seitengröße im Pager-Dropdown. Standard: 10, 20, 50, 100. |
| ``ShowPager`` | ``bool`` | ``true`` | Blendet den gesamten Pager (Seitenanzeige + Navigation) aus wenn false. Standard: true. |
| ``ShowPagerControls`` | ``bool`` | ``true`` | Blendet Navigations-Pfeile und Seitengrößen-Dropdown aus; zeigt nur den Info-Text. Standard: true. |
| ``TotalCount`` | ``int?`` | | Gesamtanzahl aller Datensätze für serverseitige Szenarien (IQueryable). Wenn gesetzt, wird dieser Wert für die Seitenberechnung verwendet. |
| ``SelectionMode`` | ``OoSelectionMode`` | ``OoSelectionMode.None`` | Selektionsmodus. None deaktiviert die Auswahl (Standard), Single erlaubt genau eine Zeile, Multiple erlaubt beliebig viele Zeilen. |
| ``SelectedItem`` | ``TItem`` | | Die aktuell selektierte Zeile im Einzel-Modus. Unterstützt @bind-SelectedItem. |
| ``SelectedItemChanged`` | ``EventCallback<TItem>`` | | EventCallback für @bind-SelectedItem. |
| ``SelectedItems`` | ``IList<TItem>`` | | Liste aller aktuell selektierten Zeilen im Mehrfach-Modus. Unterstützt @bind-SelectedItems. |
| ``SelectedItemsChanged`` | ``EventCallback<IList<TItem>>`` | | EventCallback für @bind-SelectedItems. |
| ``OnSelectionChanged`` | ``EventCallback<IList<TItem>>`` | | Wird bei jeder Änderung der Selektion ausgelöst und liefert die vollständige Liste aller selektierten Zeilen. |
| ``SaveStateEnabled`` | ``bool`` | | Aktiviert die automatische Persistenz von Sortierung, aktiver Seite und PageSize in SessionStorage. Der Storage-Key wird aus dem TItem-Typnamen automatisch abgeleitet. Beim n\u00e4chsten Seitenaufruf wird der gespeicherte Zustand wiederhergestellt. Standard: false. |
## Geerbte Parameter (OoComponentBase)
Alle nicht deklarierten HTML-Attribute (``class``, ``style``, ``data-*``, ``aria-*``, ...) werden an das Root-Element weitergereicht.
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
| ``Size`` | ``string`` | | Größe der Komponente. Mögliche Werte: OoSize.Xs, OoSize.Sm, OoSize.Md, OoSize.Lg, OoSize.Xl. Wird als CSS-Klasse am Root-Element gesetzt. |
## Hinweise
- Natives HTML-Attribut class wird automatisch an das Root-Element weitergegeben
- Natives HTML-Attribut style wird automatisch an das Root-Element weitergegeben
- Alle weiteren nicht deklarierten Attribute (data-*, aria-*, id, tabindex, …) werden ebenfalls weitergereicht
- Größe der Komponente via Size mit OoSize-Konstanten steuern (OoSize.Xs bis OoSize.Xl)
- Spalten als DataGridColumn-Kindkomponenten im Columns-RenderFragment definieren
- In-Memory-Daten: Items="@_liste" verwenden
- Serverseitige Daten: QueryableItems="@_query" hat Vorrang vor Items
- Sortierung übergabe: OnSortChanged-Callback empfängt Property und Richtung für eigene IQueryable-Logik
- State-Persistenz: SaveStateEnabled="true" speichert Sortierung, Seite und PageSize in SessionStorage
- Selektion: SelectionMode="Single" oder "Multiple" aktiviert Zeilenauswahl mit @bind-SelectedItem(s)
- Toolbar: ToolbarContent-RenderFragment erscheint rechts über der Tabelle (Export-Buttons, Aktionen)
- Scrollbare Tabelle: MaxHeight="400px" macht den Grid-Bereich scrollbar mit sticky Header