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.
Hinweis
Dieses Feature wurde in EF Core 7 hinzugefügt.
Im Reverse Engineering ist Entity Framework Core bestrebt, ein Gerüst für guten, allgemeinen Code zu erstellen, der in einer Vielzahl von App-Typen verwendet werden kann und allgemeine Codierungskonventionen für ein einheitliches Aussehen und ein vertrautes Verhalten verwendet. Manchmal sind jedoch speziellere Code- und alternative Codierungsstile wünschenswert. In diesem Artikel wird gezeigt, wie Sie den Gerüstcode mithilfe von T4-Textvorlagen anpassen.
Voraussetzungen
In diesem Artikel wird davon ausgegangen, dass Sie mit Reverse Engineering in EF Core vertraut sind. Falls nicht, lesen Sie diesen Artikel, bevor Sie fortfahren.
Hinzufügen der Standardvorlagen
Der erste Schritt zum Anpassen des Gerüstcodes besteht darin, dem Projekt die Standardvorlagen hinzuzufügen. Die Standardvorlagen sind die, die intern von EF Core beim Reverse Engineering verwendet werden. Sie bieten einen Startpunkt, um mit der Anpassung des Gerüstcodes zu beginnen.
Installieren Sie zunächst das EF Core-Vorlagenpaket für dotnet new
:
dotnet new install Microsoft.EntityFrameworkCore.Templates
Jetzt können Sie Ihrem Projekt die Standardvorlagen hinzufügen. Führen Sie dazu den folgenden Befehl aus Ihrem Projektverzeichnis aus.
dotnet new ef-templates
Mit diesem Befehl werden Ihrem Projekt die folgenden Dateien hinzugefügt.
- CodeTemplates/
- EFCore/
- DbContext.t4
- EntityType.t4
- EFCore/
Die DbContext.t4
Vorlage wird verwendet, um ein Gerüst für eine DbContext-Klasse für die Datenbank zu erstellen, und die EntityType.t4
Vorlage wird zum Erstellen von Entitätstypklassen für jede Tabelle und Ansicht in der Datenbank verwendet.
Tipp
Die T4-Erweiterung wird (anstelle von .tt) verwendet, um zu verhindern, dass Visual Studio die Vorlagen transformiert. Stattdessen werden die Vorlagen von EF Core transformiert.
Einführung in T4
Lassen Sie uns die DbContext.t4
Vorlage öffnen und deren Inhalt prüfen. Diese Datei ist eine T4-Textvorlage. T4 ist eine Sprache zum Generieren von Text mithilfe von .NET. Der folgende Code dient nur zur Veranschaulichung; sie stellt nicht den vollständigen Inhalt der Datei dar.
Wichtig
T4-Textvorlagen – insbesondere solche, die Code generieren – können ohne Syntaxmarkierung schwer zu lesen sein. Suchen Sie bei Bedarf nach einer Erweiterung für Den Code-Editor, mit der T4-Syntaxhervorhebungen ermöglicht werden.
<#@ template hostSpecific="true" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
<#@ parameter name="NamespaceHint" type="System.String" #>
<#@ import namespace="Microsoft.EntityFrameworkCore" #>
<#
if (!string.IsNullOrEmpty(NamespaceHint))
{
#>
namespace <#= NamespaceHint #>;
Die ersten Zeilen, die beginnen <#@
, werden als Direktiven bezeichnet. Sie wirken sich darauf aus, wie die Vorlage transformiert wird. In der folgenden Tabelle werden alle verwendeten Direktiven kurz beschrieben.
Richtlinie | BESCHREIBUNG |
---|---|
template |
Gibt hostSpecific="true" an, wodurch die Verwendung der Host Eigenschaft innerhalb der Vorlage für den Zugriff auf EF Core-Dienste ermöglicht wird. |
assembly |
Fügt Assemblyverweise hinzu, die zum Kompilieren der Vorlage erforderlich sind. |
parameter |
Deklariert Parameter, die beim Transformieren der Vorlage von EF Core übergeben werden. |
import |
Wie bei C# werden mithilfe von Anweisungen Namespaces in den Bereich für den Vorlagencode gebracht. |
Der nächste Abschnitt von DbContext.t4
nach den Anweisungen wird als Steuerelementblock bezeichnet. Ein Standardsteuerelementblock beginnt mit <#
und endet mit #>
. Der darin enthaltene Code wird beim Transformieren der Vorlage ausgeführt. Eine Liste der in Steuerelementblöcken verfügbaren Eigenschaften und Methoden finden Sie in der TextTransformation-Klasse .
Alles außerhalb eines Steuerelementblocks wird direkt in die Vorlagenausgabe kopiert.
Ein Ausdruckssteuerelementblock beginnt mit <#=
. Der darin enthaltene Code wird ausgewertet, und das Ergebnis wird der Vorlagenausgabe hinzugefügt. Dies ähnelt den interpolierten C#-Zeichenfolgenargumenten.
Eine ausführlichere und vollständige Erläuterung der T4-Syntax finden Sie unter Schreiben einer T4-Textvorlage.
Anpassen der Entitätstypen
Sehen wir uns an, wie sie eine Vorlage anpassen können. Standardmäßig generiert EF Core den folgenden Code für Sammlungsnavigationseigenschaften.
public virtual ICollection<Album> Albums { get; } = new List<Album>();
Die Verwendung List<T>
ist ein guter Standardwert für die meisten Anwendungen. Wenn Sie jedoch ein XAML-basiertes Framework wie WPF, WinUI oder .NET MAUI verwenden, möchten Sie häufig stattdessen ObservableCollection<T>
verwenden, um die Datenbindung zu aktivieren.
Öffnen Sie die EntityType.t4
Vorlage und suchen Sie, wo sie List<T>
generiert. Es sieht wie folgt aus:
if (navigation.IsCollection)
{
#>
public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; } = new List<<#= targetType #>>();
<#
}
Liste durch ObservableCollection ersetzen.
public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; } = new ObservableCollection<<#= targetType #>>();
Außerdem müssen wir dem Gerüstcode eine using
Direktive hinzufügen. Die Verwendungen werden in einer Liste am oberen Rand der Vorlage angegeben. Fügen Sie System.Collections.ObjectModel
zur Liste hinzu.
var usings = new List<string>
{
"System",
"System.Collections.Generic",
"System.Collections.ObjectModel"
};
Testen Sie die Änderungen mithilfe der Reverse Engineering-Befehle. Die Vorlagen innerhalb Ihres Projekts werden automatisch durch die Befehle verwendet.
dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook" Microsoft.EntityFrameworkCore.SqlServer
Wenn Sie den Befehl zuvor ausgeführt haben, fügen Sie die --force
Option zum Überschreiben der vorhandenen Dateien hinzu.
Wenn Sie alles richtig gemacht haben, sollten die Sammlungsnavigationseigenschaften nun ObservableCollection<T>
verwenden.
public virtual ICollection<Album> Albums { get; } = new ObservableCollection<Album>();
Aktualisieren von Vorlagen
Wenn Sie Ihrem Projekt die Standardvorlagen hinzufügen, wird eine Kopie dieser Vorlagen basierend auf dieser Version von EF Core erstellt. Da Fehler behoben sind und Features in nachfolgenden Versionen von EF Core hinzugefügt werden, sind Ihre Vorlagen möglicherweise veraltet. Sie sollten die änderungen, die in den EF Core-Vorlagen vorgenommen wurden, überprüfen und in Ihren angepassten Vorlagen zusammenführen.
Eine Möglichkeit, die an den EF Core-Vorlagen vorgenommenen Änderungen zu überprüfen, besteht darin, git zum Vergleichen zwischen Versionen zu verwenden. Der folgende Befehl klont das EF Core-Repository und generiert einen Diff dieser Dateien zwischen den Versionen 7.0.0 und 8.0.0.
git clone --no-checkout https://github.com/dotnet/efcore.git
cd efcore
git diff v7.0.0 v8.0.0 -- src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.tt src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.tt
Eine weitere Möglichkeit zum Überprüfen der Änderungen besteht darin, die beiden Versionen von Microsoft.EntityFrameworkCore.Templates von NuGet herunterzuladen, deren Inhalt zu extrahieren (Sie können die Dateierweiterungen in .zipändern) und diese Dateien vergleichen.
Denken Sie vor dem Hinzufügen der Standardvorlagen zu einem neuen Projekt daran, das neueste EF Core-Vorlagenpaket zu aktualisieren.
dotnet new update
Erweiterte Verwendung
Ignorieren des Eingabemodells
Die Parameter Model
und EntityType
stellen eine mögliche Methode zur Zuordnung zur Datenbank dar. Sie können Teile des Modells ignorieren oder ändern. Beispielsweise sind die von uns bereitgestellten Navigationsnamen möglicherweise nicht ideal, und Sie können sie durch Eigene ersetzen, wenn Sie das Gerüst für den Code erstellen. Andere Dinge wie Einschränkungsnamen und Indexfilter werden nur von Migrationen verwendet und können sicher aus dem Modell weggelassen werden, wenn Sie nicht beabsichtigen, Migrationen mit dem Gerüstcode zu verwenden. Ebenso können Sie Sequenzen oder Standardeinschränkungen weglassen, wenn sie von Ihrer App nicht verwendet werden.
Stellen Sie beim Vornehmen erweiterter Änderungen wie diesem sicher, dass das resultierende Modell mit der Datenbank kompatibel bleibt. Das Überprüfen des von dbContext.Database.GenerateCreateScript()
generierten SQL ist eine gute Möglichkeit, dies zu validieren.
Entitätskonfigurationsklassen
Bei großen Modellen kann die OnModelCreating-Methode der DbContext-Klasse unmanageabel groß werden. Eine Möglichkeit, dies zu beheben, ist die Verwendung von IEntityTypeConfiguration<T>
Klassen. Weitere Informationen zu diesen Klassen finden Sie unter Erstellen und Konfigurieren eines Modells .
Zum Erstellen eines Gerüsts für diese Klassen können Sie eine dritte Vorlage, wie EntityTypeConfiguration.t4
, verwenden. Wie die EntityType.t4
Vorlage wird sie für jeden Entitätstyp im Modell verwendet und verwendet den EntityType
Vorlagenparameter.
Generieren der Verknüpfungstabelle in M:N-Beziehungen
Standardmäßig generiert der Gerüstprozess keine Entität für Verknüpfungstabellen in einfachen M:N-Beziehungen. Es gibt jedoch Fälle, in denen das explizite Generieren der Verknüpfungstabelle als Entität erforderlich sein kann (z. B. wenn eine feinere Kontrolle über die generierte SQL-Abfrage erforderlich ist).
Das Gerüstverhalten für jede Entität wird von der EntityType.t4-Vorlagendatei gesteuert. In dieser Datei gibt es eine Bedingung, die die Entitätsgenerierung für einfache M:N-Verknüpfungstabellen optimiert. Um dieses Verhalten außer Kraft zu setzen und die Verknüpfungsentität zu generieren, können Sie diese Bedingung in der Datei "EntityType.t4" auskommentieren.
<#
// Comment this condition
if (EntityType.IsSimpleManyToManyJoinEntityType())
{
// Don't scaffold these
return "";
}
. . .
#>
Erstellen eines Gerüsts für andere Dateitypen
Der Hauptzweck von Reverse Engineering in EF Core besteht darin, ein Gerüst für dbContext- und Entitätstypen zu erstellen. Es gibt jedoch nichts in den Tools, das erfordern würde, dass Sie tatsächlich Gerüstcode erstellen. Sie können z. B. stattdessen ein Gerüst für ein Entitätsbeziehungsdiagramm mit Mermaid erstellen.
<#@ output extension=".md" #>
<#@ assembly name="Microsoft.EntityFrameworkCore" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
<#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #>
<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="Microsoft.EntityFrameworkCore" #>
# <#= Options.ContextName #>
```mermaid
erDiagram
<#
foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType()))
{
#>
<#= entityType.Name #> {
}
<#
foreach (var foreignKey in entityType.GetForeignKeys())
{
#>
<#= entityType.Name #> <#= foreignKey.IsUnique ? "|" : "}" #>o--<#= foreignKey.IsRequired ? "|" : "o" #>| <#= foreignKey.PrincipalEntityType.Name #> : "<#= foreignKey.GetConstraintName() #>"
<#
}
foreach (var skipNavigation in entityType.GetSkipNavigations().Where(n => n.IsLeftNavigation()))
{
#>
<#= entityType.Name #> }o--o{ <#= skipNavigation.TargetEntityType.Name #> : <#= skipNavigation.JoinEntityType.Name #>
<#
}
}
#>
```