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.
Gilt für::Azure SQL-Datenbank
Dieses Dokument zeigt, welche Änderungen in einer Entity Framework-Anwendung erforderlich sind, damit diese die Funktionen der Tools für elastische Datenbankennutzen kann. Der Schwerpunkt liegt auf der Erstellung der Shardzuordnungsverwaltung und des datenabhängigen Routings mit dem Code First-Ansatz von Entity Framework. Das Tutorial Code First für eine neue Datenbank für EF wird im gesamten Dokument als Beispiel verwendet. Der zu diesem Dokument gehörige Beispielcode ist Teil der Beispielserie der Tools für elastische Datenbanken in den Visual Studio-Codebeispielen.
Hinweis
Dieser Artikel gilt nicht für Entity Framework Core (EF Core).
Herunterladen und Ausführen des Beispielcodes
So laden Sie den Code für diesen Artikel herunter:
- Visual Studio 2012 oder höher wird vorausgesetzt.
- Laden Sie das Beispiel Elastic DB Tools for Azure SQL – Entity Framework Integration herunter. Entzippen Sie das Beispiel in einem Speicherort Ihrer Wahl.
- Starten Sie Visual Studio.
- Wählen Sie in Visual Studio „Datei“ -> „Projekt/Projektmappe öffnen“ aus.
- Navigieren Sie im Dialogfeld "Projekt öffnen" zu dem Beispiel, das Sie heruntergeladen haben, und wählen Sie
EntityFrameworkCodeFirst.sln
aus, um das Beispiel zu öffnen.
Um das Beispiel ausführen zu können, müssen Sie drei leere Datenbanken in Azure SQL-Datenbank erstellen:
- Die Datenbank "Shard Map Manager"
- Die Datenbank "Shard 1"
- Die Datenbank "Shard 2"
Nachdem Sie diese Datenbanken erstellt haben, füllen Sie die Platzhalter Program.cs
mit Ihrem Servernamen, den Datenbanknamen und Ihren Anmeldeinformationen aus, um eine Verbindung mit den Datenbanken herzustellen. Erstellen Sie die Projektmappe in Visual Studio. Visual Studio lädt die erforderlichen NuGet-Pakete für die Clientbibliothek für elastische Datenbanken, Entity Framework und die Behandlung zeitweise auftretender Fehler im Rahmen des Buildprozesses herunter. Stellen Sie sicher, dass das Wiederherstellen von NuGet-Paketen für Ihre Lösung aktiviert ist. Sie können diese Einstellung aktivieren, indem Sie im Projektmappen-Explorer von Visual Studio mit der rechten Maustaste auf die Projektmappendatei klicken.
Entity Framework-Workflows
Entity Framework-Entwickler verwenden einen der folgenden vier Workflows, um Anwendungen zu erstellen und die Persistenz von Anwendungsobjekten sicherzustellen:
- Code First (neue Datenbank): Der EF-Entwickler erstellt das Modell im Anwendungscode, und EF generiert daraus die Datenbank.
- Code First (vorhandene Datenbank): Der Entwickler lässt EF den Anwendungscode für das Modell aus einer vorhandenen Datenbank generieren.
- Model First: Der EF-Entwickler erstellt das Modell im EF-Designer, und EF erstellt dann aus diesem Modell die Datenbank.
- Database First: Der Entwickler verwendet EF-Tools, um das Modell aus einer vorhandenen Datenbank abzuleiten.
Alle diese Ansätze basieren auf der DbContext-Klasse, die Datenbankverbindungen und das Datenbankschema für eine Anwendung transparent verwaltet. Verschiedene Konstruktoren der DbContext-Basisklasse lassen verschiedene Grade der Kontrolle über das Herstellen von Verbindungen, das Datenbank-Bootstrapping und die Schemaerstellung zu. Herausforderungen ergeben sich in erster Linie aus der Tatsache, dass sich die von EF bereitgestellte Verwaltung von Datenbankverbindungen mit der Verbindungsverwaltungsfunktionen der von der Clientbibliothek für elastische Datenbanken bereitgestellten Schnittstellen für das datenabhängige Routing überschneidet.
Tools für elastische Datenbanken – Annahmen
Begriffsdefinitionen finden Sie unter Tools für elastische Datenbanken – Glossar.
Mit der Clientbibliothek für elastische Datenbanken definieren Sie Partitionen für Ihre Anwendungsdaten, die als Shardlets bezeichnet werden. Shardlets werden durch einen Sharding-Schlüssel identifiziert und bestimmten Datenbanken zugeordnet. Eine Anwendung kann beliebig viele Datenbanken haben und die Shardlets verteilen, um ausreichend Kapazität oder Leistung gemäß den aktuellen Geschäftsanforderungen zu bieten. Die Zuordnung der Sharding-Schlüsselwerte zu den Datenbanken wird in einer Shard-Zuordnung gespeichert, die durch die Client-APIs für elastische Datenbanken bereitgestellt wird. Diese Funktion wird als Shardzuordnungsverwaltung (Shard Map Management, SMM) bezeichnet. Die Shard-Zuordnung fungiert auch als Broker von Datenbankverbindungen für Anforderungen, die einen Sharding-Schlüssel enthalten. Diese Funktion wird als datenabhängiges Routingbezeichnet.
Die Shard-Zuordnungsverwaltung schützt den Benutzer vor inkonsistenten Sichten in Shardlet-Daten, die auftreten können, wenn gleichzeitige Shardlet-Verwaltungsvorgänge (z. B. das Verschieben von Daten zwischen Shards) ausgeführt werden. Dazu fungieren die von der Clientbibliothek verwalteten Shard-Zuordnungen als Broker der Datenbankverbindungen für eine Anwendung. Dadurch kann die Shardzuordnungsfunktion eine Datenbankverbindung automatisch beenden, wenn Shardverwaltungsvorgänge sich auf das Shardlet auswirken können, für das die Verbindung erstellt wurde. Bei diesem Ansatz müssen einige EF-Funktionen berücksichtigt werden, wie z. B. das Erstellen neuer Verbindungen aus einer vorhandenen Datenbank, um zu prüfen, ob die Datenbank vorhanden ist. Unserer Erfahrung nach funktionieren die DbContext-Standardkonstruktoren im Allgemeinen nur mit geschlossenen Datenbankverbindungen zuverlässig, die für EF sicher geklont werden können. Dagegen setzt das Entwurfsmodell von elastischen Datenbanken voraus, dass nur offene Verbindungen vermittelt werden. Möglicherweise könnte das Schließen einer verbindung, die von der Clientbibliothek vermittelt wird, bevor sie an den EF DbContext übergeben wird, dieses Problem lösen. Wenn die Verbindung jedoch geschlossen und somit das erneute Herstellen der Verbindung EF überlassen wird, finden die von der Bibliothek durchgeführten Gültigkeits- und Konsistenzprüfungen nicht statt. Die Migrationsfunktionalität in EF verwendet diese Verbindungen jedoch, um das zugrunde liegende Datenbankschema auf eine Weise zu verwalten, die für die Anwendung transparent ist. Im Idealfall behalten Sie alle diese Funktionen – sowohl die der Clientbibliothek für elastische Datenbanken als auch die von EF – in der gleichen Anwendung und kombinieren sie in dieser. Im folgenden Abschnitt werden diese Eigenschaften und Anforderungen detaillierter erläutert.
Requirements (Anforderungen)
Bei gleichzeitiger Verwendung der Clientbibliothek für elastische Datenbanken und der Entity Framework-APIs sollten die folgenden Eigenschaften beibehalten werden:
- Horizontale Skalierung: Datenbanken werden der Datenschicht der Anwendung entsprechend den Kapazitätsanforderungen der partitionierten Anwendung hinzugefügt oder aus dieser entfernt. Dies impliziert die Kontrolle über die Erstellung und Löschung von Datenbanken und den Einsatz der APIs für die Shardzuordnungsverwaltung von elastischen Datenbanken, um Datenbanken und die Zuordnung von Shardlets zu verwalten.
- Konsistenz: Die Anwendung nutzt Sharding und verwendet die datenabhängigen Routingfunktionen der Clientbibliothek. Um Beschädigung von Daten oder falsche Abfrageergebnisse zu vermeiden, werden Verbindungen über die Shard-Zuordnungsverwaltung vermittelt. Dadurch bleiben auch Gültigkeitsprüfung und Konsistenz gewahrt.
- Code First: Beibehalten des komfortablen Code-First-Paradigmas von EF. In Code First werden in der Anwendung vorhandene Klassen transparent den zugrunde liegenden Datenbankstrukturen zugeordnet. Der Anwendungscode arbeitet mit DbSets, wodurch die meisten Aspekte der zugrunde liegenden Datenbankverarbeitung maskiert werden.
- Schema: Entity Framework übernimmt die Schemaerstellung für die Ausgangsdatenbank und die nachfolgende Weiterentwicklung des Schemas über Migrationsvorgänge. Wenn diese Funktionen beibehalten werden, lassen sich Anwendung einfach an die Datenentwicklung anpassen.
Die folgende Anleitung beschreibt, wie diese Anforderungen für Code-First-Anwendungen unter Verwendung der Tools für elastische Datenbanken erfüllt werden.
Datenabhängiges Routing mit EF DbContext
Datenbankverbindungen mit Entity Framework werden in der Regel über Unterklassen von DbContext
verwaltet. Erstellen Sie diese Unterklassen, indem Sie von DbContext
ableiten. Hier definieren Sie Ihr DbSets
, das die datenbankgestützten Auflistungen von CLR-Objekten für Ihre Anwendung implementiert. Im Kontext des datenabhängigen Routing können Sie einige nützliche Eigenschaften identifizieren, die nicht unbedingt für andere EF Code First-Anwendungsszenarien geeignet sind:
- Die Datenbank ist bereits vorhanden und in der Shard-Zuordnung für elastische Datenbanken registriert.
- Das Schema der Anwendung wurde bereits in der Datenbank (siehe nachfolgende Erläuterung) bereitgestellt.
- Datenabhängige Routingverbindungen zur Datenbank werden durch die Shard-Zuordnung vermittelt.
DbContexts
mit datenabhängigem Routing für horizontales skalieren integrieren:
- Erstellen Sie über die Schnittstellen der Shard-Zuordnungsverwaltung für elastische Datenbanken physische Datenbankverbindungen.
- Verpacken Sie die Verbindung mit der Unterklasse
DbContext
. - Übergeben Sie die Verbindung nach unten in die
DbContext
-Basisklassen, um sicherzustellen, dass die gesamte Verarbeitung auf der EF-Seite ebenfalls stattfindet.
Das folgende Codebeispiel veranschaulicht diese Vorgehensweise. (Dieser Code ist auch im zugehörigen Visual Studio-Projekt enthalten)
public class ElasticScaleContext<T> : DbContext
{
public DbSet<Blog> Blogs { get; set; }
...
// C'tor for data-dependent routing. This call opens a validated connection
// routed to the proper shard by the shard map manager.
// Note that the base class c'tor call fails for an open connection
// if migrations need to be done and SQL credentials are used. This is the reason for the
// separation of c'tors into the data-dependent routing case (this c'tor) and the internal c'tor for new shards.
public ElasticScaleContext(ShardMap shardMap, T shardingKey, string connectionStr)
: base(CreateDDRConnection(shardMap, shardingKey, connectionStr),
true /* contextOwnsConnection */)
{
}
// Only static methods are allowed in calls into base class c'tors.
private static DbConnection CreateDDRConnection(
ShardMap shardMap,
T shardingKey,
string connectionStr)
{
// No initialization
Database.SetInitializer<ElasticScaleContext<T>>(null);
// Ask shard map to broker a validated connection for the given key
SqlConnection conn = shardMap.OpenConnectionForKey<T>
(shardingKey, connectionStr, ConnectionOptions.Validate);
return conn;
}
Hauptpunkte
Der Standardkonstruktor der DbContext-Unterklasse wird durch einen neuen Konstruktor ersetzt
Der neue Konstruktor akzeptiert die Argumente, die für das datenabhängige Routing über die Clientbibliothek für elastische Datenbanken erforderlich sind:
- die Shard-Zuordnung für den Zugriff auf datenabhängige Routing-Schnittstellen,
- den Sharding-Schlüssel zum Identifizieren des Shardlets,
- eine Verbindungszeichenfolge mit den Anmeldeinformationen für die datenabhängige Routing-Verbindung mit der Shard.
Der Aufruf des Konstruktors der Basisklasse macht einen Umweg über eine statische Methode, die alle für das datenabhängige Routing erforderlichen Schritte ausführt.
- Dazu wird die OpenConnectionForKey-Methode der Schnittstellen für Datenbankclients für die Shard-Zuordnung aufgerufen, um eine offene Verbindung herzustellen.
- Die Shard-Zuordnung erstellt die offene Verbindung mit der Shard, die das Shardlet für den gegebenen Sharding-Schlüssel enthält.
- Diese offene Verbindung wird zurück an den Basisklassenkonstruktor von DbContext übergeben, um anzugeben, dass EF diese Verbindung verwenden und nicht automatisch eine neue Verbindung erstellen soll. Auf diese Weise wird die Verbindung von der Client-API für elastische Datenbanken markiert, damit die Konsistenz unter den Shard-Zuordnungsverwaltungs-Vorgängen gewährleistet werden kann.
Verwenden Sie in Ihrem Code den neuen Konstruktor für die DbContext-Unterklasse statt des Standardkonstruktors. Beispiel:
// Create and save a new blog.
Console.Write("Enter a name for a new blog: ");
var name = Console.ReadLine();
using (var db = new ElasticScaleContext<int>(
sharding.ShardMap,
tenantId1,
connStrBldr.ConnectionString))
{
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
// Display all Blogs for tenant 1
var query = from b in db.Blogs
orderby b.Name
select b;
...
}
Der neue Konstruktor öffnet die Verbindung zum Shard, der die Daten für das Shardlet enthält, das durch den Wert tenantid1
identifiziert wird. Der Code im Block using bleibt unverändert, um auf die DbSet
für Blogs zuzugreifen, die EF auf dem Shard für tenantid1
verwenden. Dadurch wird die Semantik für den Code im using-Block so geändert, dass alle Datenbankvorgänge jetzt auf den einen Shard beschränkt sind, in dem tenantid1
gespeichert ist. Beispielsweise würde eine LINQ-Abfrage über die Blogs DbSet
nur Blogs zurückgeben, die auf dem aktuellen Shard gespeichert sind, aber nicht die auf anderen Shards gespeicherten.
Behandlung zeitweise auftretender Fehler
Das Microsoft Patterns & Practices-Team hat den Transient Fault Handling Application Block veröffentlicht. Die Bibliothek wird beim Einsatz der Clientbibliothek für elastische Datenbanken in Kombination mit EF verwendet. Achten Sie jedoch darauf, dass eine vorübergehende Ausnahme die Steuerung an eine Stelle zurückgibt, an der Sie sicherstellen können, dass nach einem vorübergehenden Fehler der neue Konstruktor verwendet wird, damit für alle neuen Verbindungsversuche die optimierten Konstruktoren verwendet werden. Andernfalls kann nicht sichergestellt werden, dass die Verbindung mit der richtigen Shard hergestellt und aufrechterhalten wird, wenn die Shard-Zuordnung verändert wird.
Das folgende Codebeispiel veranschaulicht, wie eine SQL-Wiederholungsrichtlinie für die neuen DbContext
Unterklassenkonstruktoren verwendet werden kann:
SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
{
using (var db = new ElasticScaleContext<int>(
sharding.ShardMap,
tenantId1,
connStrBldr.ConnectionString))
{
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
...
}
});
SqlDatabaseUtils.SqlRetryPolicy
im Beispielcode ist als SqlDatabaseTransientErrorDetectionStrategy
definiert, mit einer Wiederholungsanzahl von 10 und einer Wartezeit von 5 Sekunden zwischen den Wiederholungen. Dieser Ansatz ähnelt der Anleitung für EF und durch den Benutzer initiierte Transaktionen (siehe Limitations with Retrying Execution Strategies (EF6 onwards)(in englischer Sprache)). Beide Situationen erfordern, dass das Anwendungsprogramm den Bereich steuert, in dem die vorübergehende Ausnahme zurückgegeben wird: erneutes Öffnen der Transaktion oder (wie dargestellt) Neuerstellung des Kontexts von einem geeigneten Konstruktor, der die Clientbibliothek für elastische Datenbanken verwendet.
Die Notwendigkeit, zu steuern, wohin transiente Ausnahmen im Bereich zurückführen, schließt auch die Verwendung des integrierten SqlAzureExecutionStrategy
aus, das mit EF geliefert wird.
SqlAzureExecutionStrategy
würde eine Verbindung erneut öffnen, aber nicht verwenden OpenConnectionForKey
und umgehen daher alle Überprüfungen, die als Teil des OpenConnectionForKey
Anrufs ausgeführt werden. Stattdessen verwendet das Codebeispiel das integrierte DefaultExecutionStrategy
, das ebenfalls mit EF bereitgestellt wird. Im Gegensatz zu SqlAzureExecutionStrategy
funktioniert sie korrekt in Kombination mit der Wiederholungsrichtlinie von Transient Fault Handling. Die Ausführungsrichtlinie wird in der ElasticScaleDbConfiguration
Klasse festgelegt. Wir haben beschlossen, DefaultSqlExecutionStrategy
nicht zu verwenden, weil es die Verwendung von SqlAzureExecutionStrategy
vorschlägt, wenn vorübergehende Ausnahmen auftreten - was zu falschem Verhalten führen würde, wie erläutert. Weitere Informationen über die verschiedenen Wiederholungsrichtlinien und EF finden Sie unter Verbindungsstabilität in EF.
Neuschreiben von Konstruktoren
Die oben aufgeführten Codebeispiele veranschaulichen, welche Änderungen am Standardkonstruktor vorgenommen werden müssen, damit Ihre Anwendung das datenabhängige Routing mit dem Entity Framework verwenden kann. In der folgende Tabelle wird dieser Ansatz für die anderen Konstruktoren verallgemeinert.
Aktuelle Konstruktor | Für Daten veränderter Konstruktor | Basiskonstruktor | Notizen |
---|---|---|---|
MyContext() |
ElasticScaleContext(ShardMap, TKey) |
DbContext(DbConnection, bool) |
Die Verbindung muss eine Funktion der Shard-Zuordnung und des datenabhängigen Routingschlüssels sein. Sie müssen die automatische Erstellung von Verbindungen in EEF umgehen und stattdessen die Shard-Zuordnung als Verbindungsbroker verwenden. |
MyContext(string) |
ElasticScaleContext(ShardMap, TKey) |
DbContext(DbConnection, bool) |
Die Verbindung ist eine Funktion der Shard Map und des datenabhängigen Routingschlüssels. Ein fester Datenbankname oder eine Verbindungszeichenfolge funktionieren nicht, da hiermit die Überprüfung der Shardzuordnung umgangen wird. |
MyContext(DbCompiledModel) |
ElasticScaleContext(ShardMap, TKey, DbCompiledModel) |
DbContext(DbConnection, DbCompiledModel, bool) |
Die Verbindung wird für die angegebene Shardzuordnung und den Shardingschlüssel mit dem bereitgestellten Modell erstellt. Das kompilierte Modell wird an den Basiskonstruktor übergeben. |
MyContext(DbConnection, bool) |
ElasticScaleContext(ShardMap, TKey, bool) |
DbContext(DbConnection, bool) |
Die Verbindung muss aus der Shard Map und dem Schlüssel abgeleitet werden. Sie kann nicht als Eingabe bereitgestellt werden (es sei denn, in der Eingabe wurden bereits Shard-Zuordnung und Schlüssel verwendet). Der boolesche Wert wird übergeben. |
MyContext(string, DbCompiledModel) |
ElasticScaleContext(ShardMap, TKey, DbCompiledModel) |
DbContext(DbConnection, DbCompiledModel, bool) |
Die Verbindung muss aus der Shard Map und dem Schlüssel abgeleitet werden. Sie kann nicht als Eingabe bereitgestellt werden (es sei denn, in der Eingabe wurden bereits Shard-Zuordnung und Schlüssel verwendet). Das kompilierte Modell wird übergeben. |
MyContext(ObjectContext, bool) |
ElasticScaleContext(ShardMap, TKey, ObjectContext, bool) |
DbContext(ObjectContext, bool) |
Der neue Konstruktor muss sicherstellen, dass alle als Eingabe in den ObjectContext übergebenen Verbindungen an eine von Elastic Scale verwaltete Verbindung umgeleitet werden. Eine detaillierte Erläuterung von ObjectContext würde den Rahmen dieses Dokuments sprengen. |
MyContext(DbConnection, DbCompiledModel, bool) |
ElasticScaleContext(ShardMap, TKey, DbCompiledModel, bool) |
DbContext(DbConnection, DbCompiledModel, bool); |
Die Verbindung muss aus der Shard Map und dem Schlüssel abgeleitet werden. Die Verbindung kann nicht als Eingabe bereitgestellt werden (es sei denn, in der Eingabe wurden bereits Shard-Zuordnung und Schlüssel verwendet). Modell und boolescher Wert werden an den Konstruktor der Basisklasse übergeben. |
Shard-Schemabereitstellung durch EF-Migrationen
Die automatische Schemaverwaltung wird von Entity Framework bereitgestellt. Diese Möglichkeit sollte im Kontext von Anwendungen beibehalten werden, die Tools für elastische Datenbanken verwenden, um das Schema automatisch für neu erstellte Shards bereitzustellen, wenn der partitionierten Anwendung Datenbanken hinzugefügt werden. Der Hauptzweck besteht darin, für partitionierte Anwendungen die Kapazität auf Datenebene mithilfe von EF zu vergrößern. Durch die Nutzung der EF-Funktionen zur Schemaverwaltung lässt sich der Datenbankverwaltungsaufwand für die auf EF basierende partitionierte Anwendung verringern.
Die Schemabereitstellung über EF-Migrationen funktioniert am besten bei nicht geöffneten Verbindungen. Dies unterscheidet sich von dem Szenario für das datenabhängige Routing, das sich auf die von der API für elastische Datenbanken bereitgestellte geöffnete Verbindung stützt. Ein weiterer Unterschied ist die Konsistenzanforderung: Es ist zwar wünschenswert, die Konsistenz für alle datenabhängigen Routingverbindungen zum Schutz vor gleichzeitiger Manipulation der Shardzuordnung sicherzustellen, aber bei der anfänglichen Schemabereitstellung in einer neuen Datenbank, die noch nicht in der Shardzuordnung registriert wurde und folglich noch keine Shardlets enthält, ist dies nicht von Belang. Sie können daher für dieses Szenario anders als beim datenabhängigen Routing reguläre Datenbankverbindungen verwenden.
Dies führt zu einem Vorgehen, bei dem die Schemabereitstellung über EF-Migrationen eng mit der Registrierung der neuen Datenbank als Shard in der Shard-Zuordnung verbunden ist. Dabei wird Folgendes vorausgesetzt:
- Die Datenbank wurde bereits erstellt.
- Die Datenbank ist leer. Sie enthält kein Benutzerschema und keine Benutzerdaten.
- Auf die Datenbank kann für das datenabhängige Routing noch nicht über die Client-APIs für elastische Datenbanken zugegriffen werden.
Mit diesen Voraussetzungen können Sie eine reguläre ungeöffnete SqlConnection
erstellen, um die EF-Migrationen für die Bereitstellung von Schemas zu starten. Das folgende Codebeispiel veranschaulicht diese Vorgehensweise.
// Enter a new shard - i.e. an empty database - to the shard map, allocate a first tenant to it
// and kick off EF initialization of the database to deploy schema
public void RegisterNewShard(string server, string database, string connStr, int key)
{
Shard shard = this.ShardMap.CreateShard(new ShardLocation(server, database));
SqlConnectionStringBuilder connStrBldr = new SqlConnectionStringBuilder(connStr);
connStrBldr.DataSource = server;
connStrBldr.InitialCatalog = database;
// Go into a DbContext to trigger migrations and schema deployment for the new shard.
// This requires an un-opened connection.
using (var db = new ElasticScaleContext<int>(connStrBldr.ConnectionString))
{
// Run a query to engage EF migrations
(from b in db.Blogs
select b).Count();
}
// Register the mapping of the tenant to the shard in the shard map.
// After this step, data-dependent routing on the shard map can be used
this.ShardMap.CreatePointMapping(key, shard);
}
Dieses Beispiel zeigt die Methode RegisterNewShard
, die den Shard in der Shard-Zuordnung registriert, das Schema durch EF-Migrationen bereitstellt und eine Zuordnung eines Sharding-Schlüssels zu dem Shard speichert. Sie basiert auf einem Konstruktor der DbContext
Unterklasse (ElasticScaleContext
im Beispiel), der eine SQL-Verbindungszeichenfolge als Eingabe verwendet. Der Code dieses Konstruktors ist einfach, wie im folgenden Beispiel gezeigt:
// C'tor to deploy schema and migrations to a new shard
protected internal ElasticScaleContext(string connectionString)
: base(SetInitializerForConnection(connectionString))
{
}
// Only static methods are allowed in calls into base class c'tors
private static string SetInitializerForConnection(string connectionString)
{
// You want existence checks so that the schema can get deployed
Database.SetInitializer<ElasticScaleContext<T>>(
new CreateDatabaseIfNotExists<ElasticScaleContext<T>>());
return connectionString;
}
Möglicherweise muss die Version des Konstruktors, die von der Basisklasse geerbt wird, verwendet werden. Jedoch muss der Code sicherstellen, dass der Standard-Initialisierer für EF zum Herstellen der Verbindung verwendet wird. Daher der kurze Umweg in die statische Methode, bevor der Basisklassen-Konstruktor mit der Verbindungszeichenfolge aufgerufen wird. Die Registrierung von Shards sollte in einer anderen App-Domäne oder einem anderen Prozess ausgeführt werden, um sicherzustellen, dass die Initialisierungseinstellungen für EF nicht in Konflikt geraten.
Einschränkungen
Für die in diesem Dokument beschriebenen Vorgehensweisen gelten einige Einschränkungen:
- EF-Anwendungen, die
LocalDb
verwenden, müssen zuerst zu einer regulären SQL Server-Datenbank migrieren, bevor sie die elastische Datenbank-Clientbibliothek verwenden. Das Skalieren einer Anwendung durch Sharding mit Elastic Scale ist nicht möglich.LocalDb
Die Entwicklung kann weiterhinLocalDb
verwenden. - Alle Änderungen der Anwendung, die Änderungen am Datenbankschema zur Folge haben, müssen EF Migrationen in allen Shards durchlaufen. Dies wird im Beispielcode für dieses Dokument nicht veranschaulicht. Verwenden Sie Update-Database mit einem ConnectionString-Parameter zum Durchlaufen aller Shards. Oder extrahieren Sie das T-SQL-Skript für die anstehende Migration unter Verwendung von Update-Database mit der Option „-Script“, und wenden Sie das T-SQL-Skript auf die Shards an.
- Wenn eine Anforderung gegeben ist, wird davon ausgegangen, dass die damit verbundene Datenbankverarbeitung innerhalb einer einzelnen Shard erfolgt, die durch den in der Anforderung bereitgestellten Sharding-Schlüssel bezeichnet wird. Allerdings ist diese Annahme nicht immer richtig. Beispielsweise dann, wenn es nicht möglich ist, einen Sharding-Schlüssel verfügbar zu machen. Um dies zu beheben, stellt die Clientbibliothek die
MultiShardQuery
Klasse bereit, die eine Verbindungsstraktion zum Abfragen über mehrere Shards implementiert. Das Erlernen, wie man dasMultiShardQuery
in Kombination mit EF verwendet, fällt nicht in den Umfang dieses Dokuments.
Zusammenfassung
Mithilfe der in diesem Dokument beschriebenen Schritte können EF-Anwendungen die Funktion der flexiblen Datenbankclientbibliothek für datenabhängiges Routing verwenden, indem sie Konstruktoren der DbContext
in der EF-Anwendung verwendeten Unterklassen umgestalten. Dies beschränkt die erforderlichen Änderungen auf die Stellen, an denen bereits DbContext
-Klassen existieren. Darüber hinaus können EF-Anwendungen weiterhin die automatische Schemabereitstellung nutzen, indem die Schritte, mit denen die erforderlichen EF-Migrationen aufgerufen werden, mit der Registrierung der neuen Shards und Zuordnungen in der Shard-Zuordnung kombiniert werden.
Zugehöriger Inhalt
Verwenden Sie noch keine elastischen Datenbanktools? Sehen Sie sich unseren Leitfaden zu den ersten Schritten an. Wenden Sie sich bei Fragen auf der Frageseite von Microsoft Q&A für SQL-Datenbank und für Featureanforderungen an uns, fügen Sie neue Ideen hinzu, oder stimmen Sie im SQL-Datenbank-Feedbackforumüber vorhandene Ideen ab.