Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
gäller för:Azure SQL Database
Det här dokumentet är till för utvecklare som använder Dapper för att skapa program, men som också vill använda elastiska databasverktyg för att skapa program som implementerar horisontell partitionering för att skala ut sin datanivå. Det här dokumentet illustrerar de ändringar i Dapper-baserade program som krävs för att integrera med elastiska databasverktyg. Vårt fokus ligger på att skapa elastisk databashantering och databeroende routning med Dapper.
Exempelkod: Elastiska databasverktyg för Azure SQL Database – Dapper-integrering.
Det är enkelt att integrera Dapper och DapperExtensions med klientbiblioteket för elastisk databas för Azure SQL Database. Dina program kan använda databeroende routning genom att ändra skapande och öppning av nya SqlConnection-objekt för att använda OpenConnectionForKey-anropet från klientbiblioteket. Detta begränsar ändringar i ditt program till endast där nya anslutningar skapas och öppnas.
Översikt över Dapper
Dapper är en objektrelationsmappare. Den mappar .NET-objekt från ditt program till en relationsdatabas (och vice versa). Den första delen av exempelkoden visar hur du kan integrera klientbiblioteket för elastisk databas med Dapper-baserade program. Den andra delen av exempelkoden visar hur du integrerar när du använder både Dapper och DapperExtensions.
Mappningsfunktionen i Dapper tillhandahåller tilläggsmetoder för databasanslutningar som förenklar sändning av T-SQL-instruktioner för körning eller frågekörning av databasen. Dapper gör det till exempel enkelt att mappa mellan dina .NET-objekt och parametrarna för SQL-instruktioner för Execute
anrop, eller att använda resultatet av dina SQL-frågor till .NET-objekt med hjälp av Query
anrop från Dapper.
När du använder DapperExtensions behöver du inte längre ange SQL-uttrycken. Tilläggsmetoder som GetList
eller Insert
via databasanslutningen skapar SQL-uttrycken i bakgrunden.
En annan fördel med Dapper och även DapperExtensions är att programmet styr skapandet av databasanslutningen. Detta hjälper dig att interagera med det elastiska databasklientbiblioteket som förmedlar databasanslutningar baserat på mappningen av shardletar till databaser.
Information om hur du hämtar Dapper-sammansättningarna finns i Dapper dot net(Dapper dot net). Information om Dapper-tillägg finns i DapperExtensions.
En snabb titt på klientbiblioteket för elastisk databas
Med klientbiblioteket för elastisk databas definierar du partitioner av dina programdata som kallas shardletar, mappar dem till databaser och identifierar dem genom att partitionera nycklar. Du kan ha så många databaser som du behöver och distribuera dina shardlets mellan dessa databaser. Mappningen av nyckelvärden för horisontell partitionering till databaserna lagras av en shardkarta som tillhandahålls av bibliotekets API:er. Den här funktionen kallas för hantering av fragmentkartor. Shard-kartan fungerar också som koordinator för databasanslutningar för begäranden som har en partitioneringsnyckel. Den här funktionen kallas för databeroende routning.
Karthanteraren för shard skyddar användare från inkonsekventa vyer till shardlet-data som kan inträffa när samtidiga shardlet-hanteringsåtgärder utförs i databaserna. Shard Maps förmedlar databasanslutningarna för ett program som skapats med biblioteket. När shardhanteringsåtgärder kan påverka shardleten kan shardmappningsfunktionen automatiskt avsluta en databasanslutning.
I stället för att använda det traditionella sättet att skapa anslutningar för Dapper måste du använda metoden OpenConnectionForKey. Detta säkerställer att all validering sker och att anslutningar hanteras korrekt när data flyttas mellan shards.
Krav för Dapper-integrering
När du arbetar med både klientbiblioteket för elastiska databaser och Dapper-API:erna vill du behålla följande egenskaper:
- Skala ut: Vi vill lägga till eller ta bort databaser från datanivån för det fragmenterade programmet efter behov för programmets kapacitetskrav.
- Konsekvens: Eftersom programmet skalas ut med horisontell partitionering måste du utföra databeroende routning. Vi vill använda bibliotekets databeroende routningsfunktioner för att göra det. I synnerhet vill du behålla verifierings- och konsekvensgarantierna som tillhandahålls av anslutningar som hanteras via shard map manager för att undvika skador eller felaktiga frågeresultat. Detta säkerställer att anslutningar till en viss shardlet avvisas eller stoppas om (till exempel) shardleten för närvarande flyttas till en annan shard med hjälp av API:er för delning/sammanslagning.
- Objektmappning: Vi vill behålla bekvämligheten med de mappningar som tillhandahålls av Dapper för att översätta mellan klasser i programmet och de underliggande databasstrukturerna.
Följande avsnitt innehåller vägledning för dessa krav för program som baseras på Dapper och DapperExtensions.
Teknisk vägledning
Databeroende routning med Dapper
Med Dapper ansvarar programmet vanligtvis för att skapa och öppna anslutningarna till den underliggande databasen. Med en typ T
av programmet returnerar Dapper frågeresultat som .NET-samlingar av typen T
. Dapper utför mappningen från T-SQL-resultatraderna till objekt av typen T
. På samma sätt mappar Dapper .NET-objekt till SQL-värden eller parametrar för DML-instruktioner (Data Manipulation Language). Dapper erbjuder den här funktionen via tilläggsmetoder på det vanliga SqlConnection-objektet från ADO .NET SQL-klientbiblioteken. SQL-anslutningen som returneras av API:erna för elastisk skalning för DDR är också vanliga SqlConnection-objekt . På så sätt kan vi direkt använda Dapper-tillägg över den typ som returneras av klientbibliotekets DDR-API, eftersom det också är en enkel SQL-klientanslutning.
Dessa observationer gör det enkelt att använda anslutningar som förmedlas av klientbiblioteket för elastiska databaser till Dapper.
Det här kodexemplet (från det medföljande exemplet) illustrerar metoden där partitioneringsnyckeln tillhandahålls av programmet till biblioteket för att etablera anslutningen till rätt shard.
using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
key: tenantId1,
connectionString: connStrBldr.ConnectionString,
options: ConnectionOptions.Validate))
{
var blog = new Blog { Name = name };
sqlconn.Execute(@"
INSERT INTO
Blog (Name)
VALUES (@name)", new { name = blog.Name }
);
}
Anropet till OpenConnectionForKey-API :et ersätter standardskapandet och öppnandet av en SQL-klientanslutning. OpenConnectionForKey-anropet tar de argument som krävs för databeroende routning:
- Fragmentkartan för åtkomst till de databeroende routningsgränssnitten
- Partitioneringsnyckeln för att identifiera shardleten
- Autentiseringsuppgifterna (användarnamn och lösenord) för att ansluta till databaspartitionen
Shard-mappningsobjektet skapar en anslutning till fragmentet som innehåller shardleten för den angivna partitioneringsnyckeln. Klient-API:erna för elastisk databas taggar också anslutningen för att implementera dess konsekvensgarantier. Eftersom anropet till OpenConnectionForKey returnerar ett vanligt SQL-klientanslutningsobjekt följer det efterföljande anropet Execute
till tilläggsmetoden från Dapper standardmetoden Dapper.
Frågor fungerar på ett liknande sätt – du öppnar först anslutningen med OpenConnectionForKey från klient-API:n. Sedan använder du de vanliga Dapper-tilläggsmetoderna för att mappa resultatet av DIN SQL-fråga till .NET-objekt:
using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
key: tenantId1,
connectionString: connStrBldr.ConnectionString,
options: ConnectionOptions.Validate ))
{
// Display all Blogs for tenant 1
IEnumerable<Blog> result = sqlconn.Query<Blog>(@"
SELECT *
FROM Blog
ORDER BY Name");
Console.WriteLine("All blogs for tenant id {0}:", tenantId1);
foreach (var item in result)
{
Console.WriteLine(item.Name);
}
}
Använd-blocket med DDR-anslutningen begränsar alla databasåtgärder i blocket till den shard där tenantId1 lagras. Frågan returnerar endast bloggar som lagras på den aktuella skärven, men inte de som lagras på andra skärvar.
Databeroende routning med Dapper och DapperExtensions
Dapper levereras med ett ekosystem med ytterligare tillägg som kan ge ytterligare bekvämlighet och abstraktion från databasen när du utvecklar databasprogram. DapperExtensions är ett exempel.
Att använda DapperExtensions i programmet ändrar inte hur databasanslutningar skapas och hanteras. Det är fortfarande programmets ansvar att öppna anslutningar och vanliga SQL Client-anslutningsobjekt förväntas av tilläggsmetoderna. Vi kan förlita oss på OpenConnectionForKey enligt beskrivningen ovan. Som följande kodexempel visar är den enda ändringen att du inte längre behöver skriva T-SQL-uttrycken:
using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
key: tenantId2,
connectionString: connStrBldr.ConnectionString,
options: ConnectionOptions.Validate))
{
var blog = new Blog { Name = name2 };
sqlconn.Insert(blog);
}
Och här är kodexemplet för frågan:
using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
key: tenantId2,
connectionString: connStrBldr.ConnectionString,
options: ConnectionOptions.Validate))
{
// Display all Blogs for tenant 2
IEnumerable<Blog> result = sqlconn.GetList<Blog>();
Console.WriteLine("All blogs for tenant id {0}:", tenantId2);
foreach (var item in result)
{
Console.WriteLine(item.Name);
}
}
Hantera tillfälliga fel
Microsoft Patterns &Practices-teamet publicerade programblocket för övergående felhantering för att hjälpa programutvecklare att minimera vanliga tillfälliga feltillstånd som uppstod när de kördes i molnet. Mer information finns i Perseverance, Secret of All Triumphs: Användning av applikationsblocket för hantering av tillfälliga fel.
Kodexemplet förlitar sig på det tillfälliga felbiblioteket för att skydda mot tillfälliga fel.
SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
{
using (SqlConnection sqlconn =
shardingLayer.ShardMap.OpenConnectionForKey(tenantId2, connStrBldr.ConnectionString, ConnectionOptions.Validate))
{
var blog = new Blog { Name = name2 };
sqlconn.Insert(blog);
}
});
SqlDatabaseUtils.SqlRetryPolicy i koden ovan definieras som en SqlDatabaseTransientErrorDetectionStrategy med ett återförsöksantal på 10 och 5 sekunders väntetid mellan återförsök. Om du använder transaktioner kontrollerar du att omfånget för återförsök går tillbaka till början av transaktionen om det uppstår ett tillfälligt fel.
Begränsningar
De metoder som beskrivs i det här dokumentet medför ett par begränsningar:
- Exempelkoden för det här dokumentet visar inte hur du hanterar schema över shards.
- Med tanke på en begäran förutsätter vi att all databasbearbetning finns i en enda shard som identifieras av partitioneringsnyckeln som tillhandahålls av begäran. Det här antagandet gäller dock inte alltid, till exempel när det inte går att göra en horisontell partitioneringsnyckel tillgänglig. För att åtgärda detta innehåller klientbiblioteket för elastisk databas klassen MultiShardQuery. Klassen implementerar en anslutningsabstraktion för att utföra sökningar över flera dataskärvor. Att använda MultiShardQuery i kombination med Dapper ligger utanför omfånget för det här dokumentet.
Slutsats
Program som använder Dapper och DapperExtensions kan enkelt dra nytta av elastiska databasverktyg för Azure SQL Database. Genom de steg som beskrivs i det här dokumentet kan dessa program använda verktygets funktion för databeroende routning genom att ändra skapandet och öppnandet av nya SqlConnection-objekt för att använda OpenConnectionForKey-anropet för det elastiska databasklientbiblioteket. Detta begränsar de programändringar som krävs till de platser där nya anslutningar skapas och öppnas.
Relaterat innehåll
Använder du inte elastiska databasverktyg än? Kolla in vår komma igång-guide. För frågor kan du kontakta oss på Microsoft Q&En frågesida för SQL Database och för funktionsförfrågningar, lägga till nya idéer eller rösta på befintliga idéer i SQL Database-feedbackforumet.