Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
ASP.NET Core Blazor
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Die QuickGrid
Komponente ist eine Razor Komponente zum schnellen und effizienten Anzeigen von Daten in tabellarischer Form.
QuickGrid bietet eine einfache und bequeme Datenrasterkomponente für häufige Rasterrenderingszenarien und dient als Referenzarchitektur und Leistungsbaseline zum Erstellen von Datenrasterkomponenten.
QuickGrid ist hochgradig optimiert und verwendet erweiterte Techniken, um eine optimale Renderingleistung zu erzielen.
Paket
Fügen Sie einen Paketverweis für das Microsoft.AspNetCore.Components.QuickGrid
-Paket hinzu.
Hinweis
Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Beispiel-App
Verschiedene Demos zu QuickGrid finden Sie in der QuickGrid for Blazor-Beispiel-App. Die Demowebsite wird auf GitHub Pages gehostet. Die Website wird dank statischen Prerenderings mithilfe des von der Community verwalteten BlazorWasmPrerendering.Build
-GitHub-Projekts schnell geladen.
QuickGrid-Implementierung
So implementieren Sie eine QuickGrid
-Komponente:
- Geben Sie Tags für die
QuickGrid
-Komponente im Razor-Markup (<QuickGrid>...</QuickGrid>
) an. - Benennen Sie eine abfragbare Datenquelle für das Raster. Verwenden Sie eine der folgenden Datenquellen:
-
Items: Ein nullable
IQueryable<TGridItem>
, wobeiTGridItem
der Datentyp ist, der durch jede Zeile im Gitter dargestellt wird. - ItemsProvider: Ein Callback, das Daten für das Grid bereitstellt.
-
Items: Ein nullable
-
Class: Ein optionaler CSS-Klassenname. Falls angegeben, ist der Klassenname im
class
-Attribut der gerenderten Tabelle enthalten. -
Theme: Ein Themenname (Standardwert:
default
). Dies wirkt sich darauf aus, welche Formatregeln mit der Tabelle übereinstimmen. - Virtualize: Wenn 'true' ist, wird das Raster mit Virtualisierung angezeigt. Dies wird normalerweise in Verbindung mit dem Scrollen verwendet und bewirkt, dass das Raster nur die Daten um den aktuellen Scrollviewport abruft und rendert. Dies kann die Leistung beim Scrollen durch große Datasets erheblich verbessern. Wenn Sie Virtualize verwenden, sollten Sie einen Wert für ItemSize angeben und müssen sicherstellen, dass jede Zeile mit einer konstanten Höhe gerendert wird. Im Allgemeinen sollten Sie Virtualize nicht verwenden, wenn die Menge der gerenderten Daten klein ist, oder Sie die Paginierung verwenden.
- ItemSize: Gilt nur bei Verwendung von Virtualize. ItemSize definiert eine erwartete Höhe in Pixeln für jede Zeile, sodass der Virtualisierungsmechanismus die richtige Anzahl von Elementen abrufen kann, die der Anzeigegröße entspricht, und um genaues Scrollen sicherzustellen.
-
ItemKey: Definiert optional einen Wert für
@key
für jede gerenderte Zeile. In der Regel dient dies dazu, einen eindeutigen Bezeichner, z. B. einen Primärschlüsselwert, für jedes Datenelement anzugeben. So kann das Raster die Zuordnung zwischen Zeilenelementen und Datenelementen auf ihren eindeutigen Bezeichnern basierend beibehalten, auch wenn dieTGridItem
-Instanzen durch neue Kopien ersetzt werden (z. B. nach einer neuen Abfrage des zugrunde liegenden Datenspeichers). Wenn nicht festgelegt, ist@key
dieTGridItem
-Instanz. - OverscanCount: Definiert, wie viele zusätzliche Elemente vor und nach dem sichtbaren Bereich gerendert werden sollen, um die Renderingfrequenz während des Scrollens zu verringern. Während höhere Werte die Geschmeidigkeit des Scrollens verbessern können, indem mehr Elemente außerhalb des sichtbaren Bereichs gerendert werden, kann ein höherer Wert auch zu einer Erhöhung der anfänglichen Ladezeit führen. Es wird empfohlen, einen guten Ausgleich zwischen der Größe Ihres Datasets und Ihren Anforderungen an die Benutzerfreundlichkeit zu finden. Der Standardwert ist 3. Nur bei Verwendung von Virtualize verfügbar.
-
Pagination: Verknüpft diese
TGridItem
-Instanz optional mit einem PaginationState-Modell, sodass das Raster nur die aktuelle Datenseite abruft und rendert. Normalerweise wird dies in Verbindung mit einer Paginator-Komponente oder einer anderen Benutzeroberflächenlogik verwendet, die die bereitgestellte PaginationState-Instanz anzeigt und aktualisiert. - Geben Sie in dem QuickGrid untergeordneten Inhalt (RenderFragment) PropertyColumn<TGridItem,TProp>s an, die
TGridItem
-Spalten darstellen, deren Zellen Werte anzeigen:- Property: Definiert den Wert, der in den Zellen dieser Spalten angezeigt werden soll.
-
Format: Gibt optional eine Formatzeichenfolge für den Wert an. Die Verwendung von Format erfordert, dass der
TProp
-Typ IFormattable implementiert. - Sortable: Gibt an, ob die Daten nach dieser Spalte sortierbar sein sollen. Der Standardwert kann je nach Spaltentyp variieren. So wird beispielsweise ein TemplateColumn<TGridItem> sortiert, wenn ein SortBy-Parameter angegeben wird.
-
InitialSortDirection: Gibt die Sortierrichtung an, wenn IsDefaultSortColumn gleich
true
ist. - IsDefaultSortColumn: Gibt an, ob diese Spalte standardmäßig sortiert werden sollte.
- PlaceholderTemplate: Falls angegeben, verwenden virtualisierte Raster diese Vorlage, um Zellen zu rendern, deren Daten nicht geladen wurden.
- HeaderTemplate: Eine optionale Vorlage für die Kopfzelle dieser Spalte. Wenn nicht angegeben, enthält die Standardvorlage für Kopfzeilen die Title, sowie alle anwendbaren Sortierindikatoren und Optionsschaltflächen.
- Title: Titeltext für die Spalte. Der Titel wird automatisch gerendert, wenn HeaderTemplate nicht verwendet wird.
- Geben Sie Tags für die
QuickGrid
-Komponente im Razor-Markup (<QuickGrid>...</QuickGrid>
) an. - Benennen Sie eine abfragbare Datenquelle für das Raster. Verwenden Sie eine der folgenden Datenquellen:
-
Items: Ein nullable
IQueryable<TGridItem>
, wobeiTGridItem
der Datentyp ist, der durch jede Zeile im Gitter dargestellt wird. - ItemsProvider: Ein Callback, das Daten für das Grid bereitstellt.
-
Items: Ein nullable
-
Class: Ein optionaler CSS-Klassenname. Falls angegeben, ist der Klassenname im
class
-Attribut der gerenderten Tabelle enthalten. -
Theme: Ein Themenname (Standardwert:
default
). Dies wirkt sich darauf aus, welche Formatregeln mit der Tabelle übereinstimmen. - Virtualize: Wenn 'true' ist, wird das Raster mit Virtualisierung angezeigt. Dies wird normalerweise in Verbindung mit dem Scrollen verwendet und bewirkt, dass das Raster nur die Daten um den aktuellen Scrollviewport abruft und rendert. Dies kann die Leistung beim Scrollen durch große Datasets erheblich verbessern. Wenn Sie Virtualize verwenden, sollten Sie einen Wert für ItemSize angeben und müssen sicherstellen, dass jede Zeile mit einer konstanten Höhe gerendert wird. Im Allgemeinen sollten Sie Virtualize nicht verwenden, wenn die Menge der gerenderten Daten klein ist, oder Sie die Paginierung verwenden.
- ItemSize: Gilt nur bei Verwendung von Virtualize. ItemSize definiert eine erwartete Höhe in Pixeln für jede Zeile, sodass der Virtualisierungsmechanismus die richtige Anzahl von Elementen abrufen kann, die der Anzeigegröße entspricht, und um genaues Scrollen sicherzustellen.
-
ItemKey: Definiert optional einen Wert für
@key
für jede gerenderte Zeile. In der Regel dient dies dazu, einen eindeutigen Bezeichner, z. B. einen Primärschlüsselwert, für jedes Datenelement anzugeben. So kann das Raster die Zuordnung zwischen Zeilenelementen und Datenelementen auf ihren eindeutigen Bezeichnern basierend beibehalten, auch wenn dieTGridItem
-Instanzen durch neue Kopien ersetzt werden (z. B. nach einer neuen Abfrage des zugrunde liegenden Datenspeichers). Wenn nicht festgelegt, ist@key
dieTGridItem
-Instanz. -
Pagination: Verknüpft diese
TGridItem
-Instanz optional mit einem PaginationState-Modell, sodass das Raster nur die aktuelle Datenseite abruft und rendert. Normalerweise wird dies in Verbindung mit einer Paginator-Komponente oder einer anderen Benutzeroberflächenlogik verwendet, die die bereitgestellte PaginationState-Instanz anzeigt und aktualisiert. - Geben Sie in dem QuickGrid untergeordneten Inhalt (RenderFragment) PropertyColumn<TGridItem,TProp>s an, die
TGridItem
-Spalten darstellen, deren Zellen Werte anzeigen:- Property: Definiert den Wert, der in den Zellen dieser Spalten angezeigt werden soll.
-
Format: Gibt optional eine Formatzeichenfolge für den Wert an. Die Verwendung von Format erfordert, dass der
TProp
-Typ IFormattable implementiert. - Sortable: Gibt an, ob die Daten nach dieser Spalte sortierbar sein sollen. Der Standardwert kann je nach Spaltentyp variieren. So wird beispielsweise ein TemplateColumn<TGridItem> sortiert, wenn ein SortBy-Parameter angegeben wird.
-
InitialSortDirection: Gibt die Sortierrichtung an, wenn IsDefaultSortColumn gleich
true
ist. - IsDefaultSortColumn: Gibt an, ob diese Spalte standardmäßig sortiert werden sollte.
- PlaceholderTemplate: Falls angegeben, verwenden virtualisierte Raster diese Vorlage, um Zellen zu rendern, deren Daten nicht geladen wurden.
- HeaderTemplate: Eine optionale Vorlage für die Kopfzelle dieser Spalte. Wenn nicht angegeben, enthält die Standardvorlage für Kopfzeilen die Title, sowie alle anwendbaren Sortierindikatoren und Optionsschaltflächen.
- Title: Titeltext für die Spalte. Der Titel wird automatisch gerendert, wenn HeaderTemplate nicht verwendet wird.
Fügen Sie beispielsweise die folgende Komponente hinzu, um ein Raster zu rendern.
Für Blazor Web Apps muss die QuickGrid
-Komponente einen interaktiven Rendermodus übernehmen, um interaktive Funktionen wie Seitenumbruch und Sortierung zu ermöglichen.
PromotionGrid.razor
:
@page "/promotion-grid"
@using Microsoft.AspNetCore.Components.QuickGrid
<PageTitle>Promotion Grid</PageTitle>
<h1>Promotion Grid Example</h1>
<QuickGrid Items="people">
<PropertyColumn Property="@(p => p.PersonId)" Sortable="true" />
<PropertyColumn Property="@(p => p.Name)" Sortable="true" />
<PropertyColumn Property="@(p => p.PromotionDate)" Format="yyyy-MM-dd" Sortable="true" />
</QuickGrid>
@code {
private record Person(int PersonId, string Name, DateOnly PromotionDate);
private IQueryable<Person> people = new[]
{
new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
}.AsQueryable();
}
@page "/promotion-grid"
@using Microsoft.AspNetCore.Components.QuickGrid
<PageTitle>Promotion Grid</PageTitle>
<h1>Promotion Grid Example</h1>
<QuickGrid Items="people">
<PropertyColumn Property="@(p => p.PersonId)" Sortable="true" />
<PropertyColumn Property="@(p => p.Name)" Sortable="true" />
<PropertyColumn Property="@(p => p.PromotionDate)" Format="yyyy-MM-dd" Sortable="true" />
</QuickGrid>
@code {
private record Person(int PersonId, string Name, DateOnly PromotionDate);
private IQueryable<Person> people = new[]
{
new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
}.AsQueryable();
}
Greifen Sie in einem Browser über den relativen Pfad /promotion-grid
auf die Komponente zu.
Es gibt keine aktuellen Pläne, QuickGrid mit Features zu erweitern, die in vollständigen kommerziellen Rastern häufig angeboten werden, z. B. hierarchische Zeilen, durch Ziehen neu anzuordnende Spalten oder Excel-ähnliche Bereichsauswahlen. Wenn Sie erweiterte Features benötigen, die Sie nicht selbst entwickeln möchten, verwenden Sie weiterhin Raster von Drittanbietern.
Sortieren nach Spalten
Die QuickGrid
-Komponente kann Elemente nach Spalten sortieren. In Blazor Web Apps muss sich die Komponente für die Sortierung in einem interaktiven Rendermodus befinden.
Fügen Sie Sortable="true"
(Sortable) zum Tag PropertyColumn<TGridItem,TProp> hinzu:
<PropertyColumn Property="..." Sortable="true" />
Sortieren Sie in der ausgeführten App die QuickGrid-Spalte, indem Sie den gerenderten Spaltentitel auswählen.
Seitenelemente mit einer Paginator
-Komponente
Die QuickGrid
-Komponente kann Daten aus der Datenquelle seitenweise abrufen. In Blazor Web Apps muss sich die Komponente in einem interaktiven Rendermodus befinden, damit die Paginierung möglich ist.
Fügen Sie dem PaginationState-Block der Komponente eine @code
-Instanz hinzu. Legen Sie die ItemsPerPage auf die Anzahl der Elemente fest, die pro Seite angezeigt werden sollen. Im folgenden Beispiel wird die Instanz pagination
benannt, und zehn Elemente pro Seite werden festgelegt:
PaginationState pagination = new PaginationState { ItemsPerPage = 10 };
Legen Sie die QuickGrid
-Eigenschaft der Pagination-Komponente auf pagination
fest:
<QuickGrid Items="..." Pagination="pagination">
Um eine Benutzeroberfläche für die Paginierung bereitzustellen, fügen Sie eine Paginator
-Komponente über oder unter der QuickGrid
-Komponente hinzu. Legen Sie Paginator.State auf pagination
fest:
<Paginator State="pagination" />
Blättern Sie in der ausgeführten App mithilfe einer gerenderten Paginator
-Komponente durch die Elemente.
QuickGrid rendert zusätzliche leere Zeilen, um die letzte Datenseite auszufüllen, wenn sie mit einer Paginator
Komponente verwendet wird. In .NET 9 oder höher werden leere Datenzellen (<td></td>
) zu den leeren Zeilen hinzugefügt. Die leeren Zeilen sollen das Rendern der QuickGrid mit stabiler Zeilenhöhe und Formatierung auf allen Seiten erleichtern.
Zeilenstile anwenden
Anwenden von Stilen auf Zeilen mit CSS-Isolierung, die auch die Gestaltung von leeren Zeilen für QuickGrid
Komponenten, die Seitendaten mit einer Paginator
Komponente.
Wickeln Sie die QuickGrid
Komponente in einem Wrapper-Block-Element, zum Beispiel einem <div>
:
+ <div>
<QuickGrid ...>
...
</QuickGrid>
+ </div>
Wenden Sie einen Zeilenstil mit der Option ::deep
Pseudo-Element. Im folgenden Beispiel ist die Zeilenhöhe auf 2em
festgelegt, auch für leere Datenzeilen.
{COMPONENT}.razor.css
:
::deep tr {
height: 2em;
}
Alternativ können Sie auch den folgenden CSS-Stylingansatz verwenden:
- Mit Daten gefüllte Zeilenzellen anzeigen.
- Leere Zeilenzellen werden nicht angezeigt, was verhindert, dass leere Zeilenzellenränder per Bootstrap-Styling gerendert werden.
{COMPONENT}.razor.css
:
::deep tr:has(> td:not(:empty)) > td {
display: table-cell;
}
::deep td:empty {
display: none;
}
Für weitere Informationen zur Verwendung von ::deep
Pseudo-Elemente mit CSS-Isolierung, siehe ASP.NET Core Blazor CSS-Isolierung.
Benutzerdefinierte Attribute und Stile
QuickGrid unterstützt auch das Übergeben von benutzerdefinierten Attributen und Formatvorlagenklassen (Class) an das gerenderte Tabellenelement:
<QuickGrid Items="..." custom-attribute="value" Class="custom-class">
Formatieren einer Tabellenzeile basierend auf dem Zeilenelement
Wenden Sie eine Stylesheetklasse auf eine Zeile des Rasters basierend auf dem Zeilenelement mithilfe des RowClass
-Parameters an.
Im folgenden Beispiel:
- Ein Zeilenelement wird durch den
Person
Datensatzdargestellt. DerPerson
-Datensatz enthält eineFirstName
-Eigenschaft. - Die
GetRowCssClass
-Methode wendet diehighlight-row
-Klassenstile auf jede Zeile an, in der der Vorname der Person "Julie
" lautet.
<QuickGrid ... RowClass="GetRowCssClass">
...
</QuickGrid>
@code {
private record Person(int PersonId, string FirstName, string LastName);
private string GetRowCssClass(Person person) =>
person.FirstName == "Julie" ? "highlight-row" : null;
}
Schließen der QuickGrid
-Spaltenoptionen
Schließen Sie die Benutzeroberfläche für QuickGrid
-Spaltenoptionen mit der HideColumnOptionsAsync
-Methode.
Im folgenden Beispiel wird die Benutzeroberfläche für Spaltenoptionen geschlossen, sobald der Titelfilter angewendet wird:
<QuickGrid @ref="movieGrid" Items="movies">
<PropertyColumn Property="@(m => m.Title)" Title="Title">
<ColumnOptions>
<input type="search" @bind="titleFilter" placeholder="Filter by title"
@bind:after="@(() => movieGrid.HideColumnOptionsAsync())" />
</ColumnOptions>
</PropertyColumn>
<PropertyColumn Property="@(m => m.Genre)" Title="Genre" />
<PropertyColumn Property="@(m => m.ReleaseYear)" Title="Release Year" />
</QuickGrid>
@code {
private QuickGrid<Movie>? movieGrid;
private string titleFilter = string.Empty;
private IQueryable<Movie> movies = new List<Movie> { ... }.AsQueryable();
private IQueryable<Movie> filteredMovies =>
movies.Where(m => m.Title!.Contains(titleFilter));
}
EF Core-Datenquelle (Entity Framework Core)
Verwenden Sie das Factorymuster, um einen EF Core-Datenbankkontext aufzulösen, der Daten für eine QuickGrid
-Komponente bereitstellt. Weitere Informationen dazu, warum das Factorymuster empfohlen wird, finden Sie unter ASP.NET Core Blazor mit Entity Framework Core (EF Core).
Eine Datenbankkontextfactory (IDbContextFactory<TContext>) wird mithilfe der @inject
-Anweisung in die Komponente eingefügt. Der Factoryansatz erfordert das Entfernen des Datenbankkontexts, sodass die Komponente die IAsyncDisposable-Schnittstelle mithilfe der @implements
-Anweisung implementiert. Der Elementanbieter für die QuickGrid
-Komponente ist ein DbSet<T>
-Element, das aus dem erstellten Datenbankkontext (CreateDbContext) der eingefügten Datenbankkontextfactory abgerufen wird.
QuickGrid erkennt EF-bereitgestellte IQueryable Instanzen und weiß, wie Abfragen asynchron zur Steigerung der Effizienz aufgelöst werden.
Fügen Sie einen Paketverweis für das Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter
-NuGet-Paket hinzu.
Hinweis
Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Rufen Sie AddQuickGridEntityFrameworkAdapter in der Dienstsammlung in der Datei Program
auf, um eine Implementierung von IAsyncQueryExecutor mit EF-Unterstützung zu registrieren:
builder.Services.AddQuickGridEntityFrameworkAdapter();
Im folgenden Beispiel wird eine ExampleTable
DbSet<TEntity> (Tabelle) aus einem AppDbContext
-Datenbankkontext (context
) als Datenquelle für eine QuickGrid
-Komponente verwendet:
@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<AppDbContext> DbFactory
...
<QuickGrid ... Items="context.ExampleTable" ...>
...
</QuickGrid>
@code {
private AppDbContext context = default!;
protected override void OnInitialized()
{
context = DbFactory.CreateDbContext();
}
public async ValueTask DisposeAsync() => await context.DisposeAsync();
}
Im Codeblock (@code
) des vorherigen Beispiels finden Sie Folgendes:
- Das Feld
context
enthält den Datenbankkontext, der alsAppDbContext
eingegeben wird. - Die Lebenszyklusmethode
OnInitialized
weist dem CreateDbContext-Feld aus der eingefügten Factory (context
) einen neuen Datenbankkontext (DbFactory
) zu. - Die asynchrone
DisposeAsync
-Methode entsorgt den Datenbankkontext, wenn die Komponente beseitigt wird.
Sie können auch einen beliebigen EF-unterstützten LINQ-Operator verwenden, um die Daten zu filtern, bevor Sie sie an den Parameter Items übergeben.
Im folgenden Beispiel werden Filme nach einem Filmtitel gefiltert, der in ein Suchfeld eingegeben wird. Der Datenbankkontext lautet BlazorWebAppMoviesContext
und das Modell Movie
. Die Title
-Eigenschaft des Films wird für den Filtervorgang verwendet.
@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<BlazorWebAppMoviesContext> DbFactory
...
<p>
<input type="search" @bind="titleFilter" @bind:event="oninput" />
</p>
<QuickGrid ... Items="FilteredMovies" ...>
...
</QuickGrid>
@code {
private string titleFilter = string.Empty;
private BlazorWebAppMoviesContext context = default!;
protected override void OnInitialized()
{
context = DbFactory.CreateDbContext();
}
private IQueryable<Movie> FilteredMovies =>
context.Movie.Where(m => m.Title!.Contains(titleFilter));
public async ValueTask DisposeAsync() => await context.DisposeAsync();
}
Ein funktionierendes Beispiel finden Sie in den folgenden Ressourcen:
- Erstellen eines Lernprogramms für eine Blazor Filmdatenbank-App
-
Blazor Beispiel-App für Filmdatenbanken: Wählen Sie den Ordner "Neueste Version" im Repository aus. Der Beispielordner für das Projekt des Lernprogramms heißt
BlazorWebAppMovies
.
Unterstützung für Anzeigenamen
Ein Spaltentitel kann mithilfe von ColumnBase<TGridItem>.Title im Tag von PropertyColumn<TGridItem,TProp> zugewiesen werden. Im folgenden Filmbeispiel erhält die Spalte den Namen „Release Date
“ für die Daten zum Filmstartdatum in der Spalte:
<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
Das Verwalten von Spaltentiteln (Namen) aus gebundenen Modelleigenschaften ist in der Regel jedoch die bessere Option für die Verwaltung einer App. Ein Modell kann den Anzeigenamen einer Eigenschaft mit dem [Display]
-Attribut steuern. Im folgenden Beispiel gibt das Modell für seine Release Date
-Eigenschaft den Anzeigenamen „ReleaseDate
“ für das Startdatum eines Films an:
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
Damit die QuickGrid
-Komponente die DisplayAttribute.Name-Eigenschaft verwenden kann, ordnen Sie der PropertyColumn<TGridItem,TProp>-Komponente eine Unterklasse zu, entweder in der Komponente selbst oder in einer separaten Klasse. Rufen Sie die Methode GetName auf, um den lokalisierten DisplayAttribute.Name Wert zurückzugeben, wenn ein nicht lokalisiertes DisplayName ([DisplayName]
Attribut) den Wert nicht enthält:
public class DisplayNameColumn<TGridItem, TProp> : PropertyColumn<TGridItem, TProp>
{
protected override void OnParametersSet()
{
if (Title is null && Property.Body is MemberExpression memberExpression)
{
var memberInfo = memberExpression.Member;
Title =
memberInfo.GetCustomAttribute<DisplayNameAttribute>().DisplayName ??
memberInfo.GetCustomAttribute<DisplayAttribute>().GetName() ??
memberInfo.Name;
}
base.OnParametersSet();
}
}
Verwenden Sie die Unterklasse in der Komponente QuickGrid
. Im folgenden Beispiel wird die vorangehende DisplayNameColumn
verwendet. Der Name „Release Date
“ wird vom [Display]
-Attribut im Modell bereitgestellt, sodass Title nicht angegeben werden muss:
<DisplayNameColumn Property="movie => movie.ReleaseDate" />
Das [DisplayName]
-Attribut wird ebenfalls unterstützt:
[DisplayName("Release Date")]
public DateTime ReleaseDate { get; set; }
Das Attribut [Display]
wird jedoch empfohlen, da es zusätzliche Eigenschaften bereitstellt. Beispielsweise bietet das Attribut [Display]
die Möglichkeit, einen Ressourcentyp für die Lokalisierung zuzuweisen.
Daten aus der Ferne
In Blazor WebAssembly-Apps ist das Abrufen von Daten aus einer JSON-basierten Web-API auf einem Server eine gängige Anforderung. Verwenden Sie den Parameter ItemsProvider, um nur die Daten abzurufen, die für die aktuelle Seite/den Viewport von Daten erforderlich sind, und um Sortier- oder Filterregeln auf dem Server anzuwenden.
ItemsProvider kann auch in einer serverseitigen Blazor-App verwendet werden, wenn die App zum Abfragen eines externen Endpunkts oder in anderen Fällen erforderlich ist, in denen die Anforderungen nicht von IQueryable abgedeckt werden.
Geben Sie einen Rückruf an, der dem Delegattyp GridItemsProvider<TGridItem> entspricht, wobei TGridItem
der Datentyp ist, der im Raster angezeigt wird. Dem Rückruf wird ein Parameter vom Typ GridItemsProviderRequest<TGridItem> zugewiesen, der den Startindex, die maximale Zeilenanzahl und die Sortierreihenfolge der zurückzugebenden Daten angibt. Neben der Rückgabe der übereinstimmenden Elemente ist auch eine Gesamtzahl der Elemente (totalItemCount
) erforderlich, damit Paging und Virtualisierung ordnungsgemäß funktionieren.
Im folgenden Beispiel werden Daten aus der öffentlichen OpenFDA Food Enforcement-Datenbank abgerufen.
GridItemsProvider<TGridItem> konvertiert GridItemsProviderRequest<TGridItem> in eine Abfrage für die OpenFDA-Datenbank. Abfrageparameter werden in das jeweilige URL-Format übersetzt, das von der externen JSON-API unterstützt wird. Es ist nur möglich, Sortier- und Filtervorgänge über Sortierung und Filterung durchzuführen, die von der externen API unterstützt wird. Der OpenFDA-Endpunkt unterstützt keine Sortierung, sodass keine der Spalten als sortierbar gekennzeichnet ist. Er unterstützt jedoch das Überspringen von Datensätzen (Parameter skip
) und das Einschränken der Rückgabe von Datensätzen (Parameter limit
), sodass die Komponente die Virtualisierung aktivieren und schnell einen Bildlauf durch Zehntausende von Datensätzen durchführen kann.
FoodRecalls.razor
:
@page "/food-recalls"
@inject HttpClient Http
@inject NavigationManager Navigation
<PageTitle>Food Recalls</PageTitle>
<h1>OpenFDA Food Recalls</h1>
<div class="grid" tabindex="-1">
<QuickGrid ItemsProvider="@foodRecallProvider" Virtualize="true">
<PropertyColumn Title="ID" Property="@(c => c.Event_Id)" />
<PropertyColumn Property="@(c => c.State)" />
<PropertyColumn Property="@(c => c.City)" />
<PropertyColumn Title="Company" Property="@(c => c.Recalling_Firm)" />
<PropertyColumn Property="@(c => c.Status)" />
</QuickGrid>
</div>
<p>Total: <strong>@numResults results found</strong></p>
@code {
private GridItemsProvider<FoodRecall>? foodRecallProvider;
private int numResults;
protected override async Task OnInitializedAsync()
{
foodRecallProvider = async req =>
{
var url = Navigation.GetUriWithQueryParameters(
"https://api.fda.gov/food/enforcement.json",
new Dictionary<string, object?>
{
{ "skip", req.StartIndex },
{ "limit", req.Count },
});
using var response = await Http.GetFromJsonAsync<FoodRecallQueryResult>(
url, req.CancellationToken);
return GridItemsProviderResult.From(
items: response!.Results,
totalItemCount: response!.Meta.Results.Total);
};
numResults = (await Http.GetFromJsonAsync<FoodRecallQueryResult>(
"https://api.fda.gov/food/enforcement.json"))!.Meta.Results.Total;
}
}
Weitere Informationen zum Aufrufen von Web-APIs finden Sie unter Aufrufen einer Web-API aus einer ASP.NET Core Blazor-App.
QuickGrid-Gerüstgenerator
Das QuickGrid-Gerüst erstellt Gerüste für Razor-Komponenten mit QuickGrid zum Anzeigen von Daten aus einer Datenbank.
Das Gerüst generiert grundlegende Create-, Read-, Update- und Delete-Seiten (CRUD), die auf einem Entity Framework Core-Datenmodell basieren. Sie können ein Gerüst für einzelne Seiten oder alle CRUD-Seiten erstellen. Sie wählen die Modellklasse und DbContext
aus, und erstellen optional ein neues DbContext
-Modell aus, falls erforderlich.
Die Razor-Gerüstkomponenten werden dem Projekt in einem generierten Ordner hinzugefügt, der nach der Modellklasse benannt ist. Die generierte Index
-Komponente verwendet eine QuickGrid
-Komponente, um die Daten anzuzeigen. Passen Sie die generierten Komponenten nach Bedarf an und aktivieren Sie die Interaktivität, um interaktive Features wie Seitennummerierung, Sortieren und Filtern zu nutzen.
Die vom Gerüst erzeugten Komponenten erfordern serverseitiges Rendering (SSR), sodass sie bei der Ausführung auf WebAssembly nicht unterstützt werden.
Klicken Sie mit der rechten Maustaste auf den Ordner Components/Pages
, und wählen Sie Hinzufügen>Neues Gerüstelement aus.
Wenn das Dialogfeld
CRUD ist ein Akronym für Create, Read, Update und Delete. Der Gerüstgenerator erzeugt Komponenten für Erstellung, Bearbeitung, Löschung, Details und Indizes für die App.
Vervollständigen Sie das Dialogfeld Komponenten hinzufügen mit Entity Framework (CRUD)Razor:
- Die Dropdownliste Vorlage enthält weitere Vorlagen speziell zum Erstellen von Erstellen-, Bearbeiten-, Löschen-, Details- und Liste-Komponenten. Diese Dropdownliste ist praktisch, wenn Sie nur einen bestimmten Typ von Komponentengerüst für eine Modellklasse erstellen müssen. Übernehmen Sie in der Dropdownliste Vorlage die Einstellung CRUD, um ein Gerüst für einen vollständigen Komponentensatz zu erstellen.
- Wählen Sie in der Dropdownliste Modellklasse die Modellklasse aus. Für die generierten Komponenten wird aus dem Modellnamen ein Ordner erstellt. Wenn die Modellklasse
Movie
heißt, wird der Ordner automatischMoviePages
genannt. - Für die Klasse DbContext wählen Sie einen der folgenden Ansätze:
- Wählen Sie eine vorhandene DbContext-Klasse, von der Sie wissen, dass sie eine Factory Provider Registrierung (AddDbContextFactory) hat.
- Wählen Sie die Schaltfläche + (Pluszeichen) und verwenden Sie das modale Dialogfeld Datenkontext hinzufügen, um einen neuen DbContext-Klassennamen anzugeben, mit dem die Klasse bei einem Factory-Anbieter registriert wird, anstatt den Kontexttyp direkt als Dienstregistrierung zu verwenden.
- Nachdem das modale Dialogfeld geschlossen wurde, wird die Dropdownliste Datenbankanbieter als Standard auf SQL Server festgelegt. Sie können den entsprechenden Anbieter für die Datenbank auswählen, die Sie verwenden. Zu den Optionen gehören SQL Server, SQLite, PostgreSQL und Azure Cosmos DB.
- Wählen Sie Hinzufügen.
Ein Beispiel für die Verwendung des Gerüsts finden Sie unter Erstellen einer Filmdatenbank-App (Übersicht).For an example use of the QuickGrid scaffolder, see Build a Blazor movie database app (Overview).
Mehrere gleichzeitige EF Core Abfragen lösen System.InvalidOperationException
aus
Mehrere gleichzeitige EF Core-Abfragen können folgende System.InvalidOperationException auslösen:
System.InvalidOperationException: Für diese Kontextinstanz wurde ein zweiter Vorgang gestartet, bevor ein vorheriger Vorgang abgeschlossen wurde. Dies wird in der Regel durch verschiedene Threads verursacht, die gleichzeitig dieselbe Instanz von DbContext verwenden. Weitere Informationen zum Vermeiden von Threadingproblemen mit DbContext finden Sie unter https://go.microsoft.com/fwlink/?linkid=2097913.
Dieses Szenario ist für eine Verbesserung in einer bevorstehenden Version von ASP.NET Core geplant. Weitere Informationen finden Sie unter [Blazor] Verbessern der Benutzererfahrung mit QuickGrid und EF Core (dotnet/aspnetcore
#58716).
In der Zwischenzeit können Sie das Problem mithilfe eines ItemsProvider und eines Abbruchtokens beheben. Das Abbruchtoken verhindert gleichzeitige Abfragen, indem die vorherige Anforderung abgebrochen wird, wenn eine neue Anforderung ausgestellt wird.
Sehen Sie sich das folgende Beispiel an. Es basiert auf der Index
-Komponente der Filmdatenbank zum Tutorial Erstellen einer Blazor-Filmdatenbank-App (Übersicht). Die einfachere Version, die als Gerüst in der App erstellt wurde, wird unter Beispiel-App des Artikels vorgestellt. Die Index
-Komponente, die in die App integriert wurde, wird durch die folgende Komponente ersetzt.
Components/Pages/MoviePages/Index.razor
:
@page "/movies"
@rendermode InteractiveServer
@using Microsoft.EntityFrameworkCore
@using Microsoft.AspNetCore.Components.QuickGrid
@using BlazorWebAppMovies.Models
@using BlazorWebAppMovies.Data
@inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory
<PageTitle>Index</PageTitle>
<h1>Index</h1>
<div>
<input type="search" @bind="titleFilter" @bind:event="oninput" />
</div>
<p>
<a href="movies/create">Create New</a>
</p>
<div>
<QuickGrid Class="table" TGridItem="Movie" ItemsProvider="GetMovies"
ItemKey="(x => x.Id)" Pagination="pagination">
<PropertyColumn Property="movie => movie.Title" Sortable="true" />
<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
<PropertyColumn Property="movie => movie.Genre" />
<PropertyColumn Property="movie => movie.Price" />
<PropertyColumn Property="movie => movie.Rating" />
<TemplateColumn Context="movie">
<a href="@($"movies/edit?id={movie.Id}")">Edit</a> |
<a href="@($"movies/details?id={movie.Id}")">Details</a> |
<a href="@($"movies/delete?id={movie.Id}")">Delete</a>
</TemplateColumn>
</QuickGrid>
</div>
<Paginator State="pagination" />
@code {
private BlazorWebAppMoviesContext context = default!;
private PaginationState pagination = new PaginationState { ItemsPerPage = 5 };
private string titleFilter = string.Empty;
public async ValueTask<GridItemsProviderResult<Movie>> GetMovies(GridItemsProviderRequest<Movie> request)
{
using var context = DbFactory.CreateDbContext();
var totalCount = await context.Movie.CountAsync(request.CancellationToken);
IQueryable<Movie> query = context.Movie.OrderBy(x => x.Id);
query = request.ApplySorting(query).Skip(request.StartIndex);
if (request.Count.HasValue)
{
query = query.Take(request.Count.Value);
}
var items = await query.ToArrayAsync(request.CancellationToken);
var result = new GridItemsProviderResult<Movie>
{
Items = items,
TotalItemCount = totalCount
};
return result;
}
}