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.
In diesem Tutorial nehmen Sie das Beispiel Microsoft.Samples.XMLA.ExecuteQueries – eine .NET-Web-API, die DAX-Abfragen mithilfe von ADOMD.NET über den XMLA-Endpunkt ausführt – und ändern es so, dass die Execute DAX Queries REST-API verwendet wird, die Ergebnisse im Apache Arrow IPC-Format zurückgibt. Das Beispiel stellt das Mid-Tier-Framework (Routing, Rate Limiting, Health Probe) bereit. In diesem Tutorial erfahren Sie, wie Sie die XMLA/ADOMD-Abfrage-Ausführungsstruktur durch REST-API-Aufrufe und Arrow-IPC-Antwortbehandlung ersetzen.
Voraussetzungen
- .NET 8 SDK oder höher.
- Ein Power-BI-Arbeitsbereich in Premium- oder Fabric-Kapazität mit mindestens einem Semantikmodell.
- Eine Microsoft Entra App-Registrierung mit einem geheimen Clientschlüssel.
- Der Dienstprinzipal, der als Arbeitsbereichsmitglied mit Mitwirkenderrolle (oder höher) hinzugefügt wurde.
- Die folgenden Mandanteneinstellungen sind aktiviert:
- Dataset Execute Queries REST API und Zulassen, dass Dienstprinzipale Power BI-APIs verwenden (unter Entwicklereinstellungen).
- Ermöglichen von XMLA-Endpunkten sowie der Analyse in Excel mit lokalen semantischen Modellen (unter Integrationseinstellungen).
Ausführliche Informationen zur Beispieldienstarchitektur finden Sie unter sample README.
Bevor Sie anfangen
Der Beispieldienst verwendet den XMLA-Endpunkt mit ADOMD.NET. Mit diesem Tutorial wird es so angepasst, dass die REST-API "Execute DAX Queries" verwendet wird, die Ergebnisse im Apache Arrow IPC-Format zurückgibt. Beide Ansätze ermöglichen es Ihnen, DAX-Abfragen mit Power BI semantischen Modellen auszuführen, unterscheiden sich jedoch auf wichtige Weise.
| XMLA/ ADOMD.NET | Ausführen der REST-API für DAX-Abfragen | |
|---|---|---|
| Protokoll | XMLA über HTTPS (proprietäre Binärdatei) | Standard REST (HTTP POST /response) |
| Clientbibliothek |
Microsoft.AnalysisServices.AdomdClient – Windows-orientiertes (.NET Core-Paket verfügbar, aber eingeschränkte plattformübergreifende Unterstützung), verwaltet Sitzungen und Verbindungen. |
HttpClient
+
Apache.Arrow — leichtgewichtig, plattformübergreifend, zustandslos |
| Authentifizierung | Verbindungszeichenfolge mit Zugriffstoken; Sitzung auf Verbindungsebene | Bearer-Token für jede Anforderung; kein Session-Zustand |
| Antwortformat | Tabellarische Rowsets, die von der ADOMD-Clientbibliothek analysiert werden | Apache Arrow IPC – ein spaltenbasiertes Binärformat mit breiter Ökosystemunterstützung (Python, R, Spark, DuckDB) |
| Verbindungsverwaltung | Erfordert, dass das Pooling die Sitzungseinrichtungskosten amortisiert. | Zustandsloses HTTP – kein Pooling erforderlich; MSAL behandelt den Token-Cache |
| Am besten geeignet für | Legacy-Integrationen, MDX-Abfragen, feingranulierte Sitzungssteuerung | Neue Dienste, bei denen Sie eine einfachere HTTP-Integration, spaltenübergreifende Leistung oder sprachübergreifende Verbraucher wünschen |
Wählen Sie die REST-API Execute DAX Queries REST API aus, wenn Sie einen neuen Dienst erstellen oder die nachgeschalteten Verbraucher von Arrow IPC profitieren können (z. B. Analysepipelinen, Python Notizbücher oder Spaltendatenbanken). Behalten Sie XMLA/ADOMD bei, wenn Sie MDX-Unterstützung benötigen oder von Features auf Sitzungsebene abhängen, wie z. B. für eine Sitzung geltende berechnete Mitglieder.
1 – Klonen und Überprüfen des Beispiels
Klonen Sie das Repository, und bestätigen Sie, dass es kompiliert wird:
git clone https://github.com/dbrownems/Microsoft.Samples.XMLA.ExecuteQueries.git
cd Microsoft.Samples.XMLA.ExecuteQueries
dotnet build
Die Lösung enthält zwei Projekte: den Mid-Tier-Dienst (Microsoft.Samples.XMLA.ExecuteQueries) und einen Ladetestclient (Tester). Sie müssen den ursprünglichen Dienst nicht für einen Livearbeitsbereich ausführen . Überprüfen Sie einfach, ob der Build erfolgreich ist, bevor Sie Änderungen vornehmen.
2 – Aktualisieren von NuGet-Abhängigkeiten
Entfernen Sie im projekt Microsoft.Samples.XMLA.ExecuteQueries das ADOMD.NET paket, und fügen Sie Pakete für die Pfeil-API hinzu:
cd Microsoft.Samples.XMLA.ExecuteQueries
dotnet remove package Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64
dotnet add package Apache.Arrow
dotnet add package Microsoft.Identity.Client
Behalten Sie das paket Microsoft.PowerBI.Api bei, wenn Sie die Anforderungs-/Antwortmodelltypen wiederverwenden möchten. entfernen Sie es andernfalls, und definieren Sie Eigene DTOs.
3 – Ersetzen des ADOMD-Verbindungspools durch MSAL-Tokenzwischenspeicherung
Im Beispiel werden AdomdConnectionPool.cs verwendet, um XMLA-Verbindungen zu poolen. Die Arrow-API ist ein zustandsloser REST-Endpunkt, sodass Sie das Verbindungspooling durch die MSAL-Tokenzwischenspeicherung ersetzen.
Erstellen sie eine neue Datei TokenService.cs:
using Microsoft.Identity.Client;
public class TokenService
{
private readonly IConfidentialClientApplication _app;
private readonly string[] _scopes =
{ "https://analysis.windows.net/powerbi/api/.default" };
public TokenService(IConfiguration config)
{
_app = ConfidentialClientApplicationBuilder
.Create(config["PowerBI:ClientId"])
.WithClientSecret(config["PowerBI:ClientSecret"])
.WithAuthority(AzureCloudInstance.AzurePublic,
config["PowerBI:TenantId"])
.Build();
}
public async Task<string> GetAccessTokenAsync()
{
var result = await _app
.AcquireTokenForClient(_scopes).ExecuteAsync();
return result.AccessToken;
}
}
MSAL speichert Token automatisch zwischen – nachfolgende Aufrufe geben das zwischengespeicherte Token zurück, bis es abläuft.
Löschen AdomdConnectionPool.cs und AdomdExtensions.cs. Sie werden nicht mehr benötigt.
4 – Aktualisieren des Abfragehandlers zum Aufrufen der Pfeil-API
In Handlers.cs ersetzen Sie die ADOMD-Abfrageausführung mit einem HTTP-Aufruf zu dem Endpunkt für "Execute DAX Queries".
Entfernen Sie alle ADOMD-Verweise (AdomdConnectionPool, AdomdConnection, AdomdCommand, WrappedConnection). Ändern Sie die injizierten Abhängigkeiten des Handlers zu TokenService und HttpClient anstelle von Verbindungspools und Arbeitsbereichsabfragen.
Erstellen Sie die REST-API-URL aus dem Arbeitsbereich und den Dataset-GUIDs, die bereits in den Routenparametern verfügbar sind:
var url = $"https://api.powerbi.com/v1.0/myorg/groups/{workspaceId}"
+ $"/datasets/{datasetId}/executeDaxQueries";
Die DAX-Abfrage in einem JSON-Anforderungstext posten.
var token = await tokenService.GetAccessTokenAsync();
using var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent(
JsonSerializer.Serialize(new { query, queryTimeout = 120 }),
Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(
request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
Verwenden Sie HttpCompletionOption.ResponseHeadersRead, damit der Antworttextkörper ohne Pufferung gestreamt wird, was bei großen Resultsets wichtig ist.
5 – Verarbeitung der Arrow-IPC-Antwort
Die Execute DAX Queries-API gibt einen oder mehrere Arrow IPC-Datenströme zurück, die im Antwortkörper verkettet sind. Jeder Datenstrom enthält Schemametadaten, die seinen Zweck angibt:
- Datenergebnis – die Abfrageergebnisse (keine speziellen Metadatenkennzeichnungen).
-
Fehlerergebnis –
IsError=truein den Schemametadaten mitFaultCodeundFaultStringWerten. -
Ausführungsmetriken –
IsExecMetrics=true(wenn Sie Metriken über denexecutionMetricsParameter angefordert haben).
Ersetzen Sie DataResult.cs durch eine Logik, die die Arrow-Antwort verarbeitet. Wenn Ihre mittlere Ebene arrow IPC einfach an nachgeschaltete Consumer weiterleitet, streamen Sie die Bytes ohne Deserialisierung:
context.Response.ContentType = "application/vnd.apache.arrow.stream";
await response.Content.CopyToAsync(context.Response.Body);
Wenn Sie Ergebnisse prüfen oder Formate konvertieren müssen, deserialisieren Sie den Pfeildatenstrom mit ArrowStreamReader:
using var stream = await response.Content.ReadAsStreamAsync();
using var reader = new ArrowStreamReader(stream);
while (true)
{
var batch = await reader.ReadNextRecordBatchAsync();
if (batch == null) break;
// Process batch — convert to JSON, filter rows, etc.
}
Überprüfen Sie die Schemametadaten, um Fehlerantworten zu erkennen:
var metadata = reader.Schema.Metadata;
if (metadata.TryGetValue("IsError", out var isError)
&& isError == "true")
{
var faultCode = metadata.GetValueOrDefault(
"FaultCode", "Unknown");
var faultString = metadata.GetValueOrDefault(
"FaultString", "Unknown error");
// Return error to caller
}
6 – Vereinfachen der Arbeitsbereichskonfiguration
Im Beispiel appsettings.json werden XMLA-Endpunkte und Datensatznamensuchvorgänge konfiguriert, da ADOMD eine Verbindung nach Katalognamen herstellt. Die Arrow-REST-API verwendet die GUIDs des Arbeitsbereichs und des Datasets direkt aus der Anforderungs-URL, wodurch die Konfiguration vereinfacht wird.
Aktualisieren Sie appsettings.json mit Ihren Dienstprinzipalanmeldeinformationen, und entfernen Sie die XMLA-spezifischen Felder:
{
"PowerBI": {
"TenantId": "YOUR_TENANT_ID",
"ClientId": "YOUR_APP_CLIENT_ID",
"ClientSecret": "YOUR_CLIENT_SECRET"
}
}
Der Workspaces Abschnitt mit XmlaEndpoint und Datasets Arrays ist nicht mehr erforderlich. Sie können Workspace.cs und Dataset.cs löschen oder die Datasets-Liste als Whitelist für die Governance verwenden, um einzuschränken, welche Datasets der Dienst abfragen kann.
7 – Registrieren von Diensten und Aktualisieren des Routings
Ersetzen Sie in Program.cs die ADOMD-Pool- und Arbeitsbereichsregistrierungen durch die neuen Dienste:
builder.Services.AddSingleton<TokenService>();
builder.Services.AddHttpClient();
Aktualisieren Sie die Route so, dass sie mit dem Endpunktmuster "DAX-Abfragen ausführen" übereinstimmt:
app.MapPost(
"/v1.0/myorg/groups/{workspaceId:Guid}"
+ "/datasets/{datasetId:Guid}/executeDaxQueries",
Handlers.ExecuteDaxQueriesInGroup);
Der vorhandene Ratenbegrenzer, die Gesundheitsprüfung und der Anfragesteller aus dem Beispiel bleiben unverändert nützlich.
8 – Testen des Diensts
Führen Sie den Dienst aus:
dotnet run --project Microsoft.Samples.XMLA.ExecuteQueries
Senden Sie von einem anderen Terminal aus eine DAX-Abfrage:
curl -X POST https://localhost:3000/v1.0/myorg/groups/YOUR_WORKSPACE_ID/datasets/YOUR_DATASET_ID/executeDaxQueries \
-H "Content-Type: application/json" \
-d '{"query": "EVALUATE TOPN(5, '\''DimProduct'\'')"}'
Die Antwort ist ein binärer Arrow-IPC-Datenstrom. Speichern Sie sie in einer Datei, und prüfen Sie sie mit Python:
curl -s -o result.arrow https://localhost:3000/v1.0/myorg/groups/YOUR_WORKSPACE_ID/datasets/YOUR_DATASET_ID/executeDaxQueries \
-H "Content-Type: application/json" \
-d '{"query": "EVALUATE TOPN(5, '\''DimProduct'\'')"}'
python -c "
import pyarrow as pa
reader = pa.ipc.open_stream('result.arrow')
table = reader.read_all()
print(table.schema)
print(table.to_pandas())
"
Zusammenfassung der Änderungen
| Originaldatei | Action |
|---|---|
AdomdConnectionPool.cs |
Löschen – ersetzt durch MSAL-Token-Caching in TokenService.cs |
AdomdExtensions.cs |
Löschen – JSON-Streaminglogik nicht mehr erforderlich |
DataResult.cs |
Neu schreiben – Arrow-IPC streamen oder mit ArrowStreamReader deserialisieren |
Handlers.cs |
Neuschreiben – HTTP POST zum Ausführen von DAX-Abfragen mit der API anstelle der ADOMD-Ausführung |
Workspace.cs / Dataset.cs |
Vereinfachen oder Löschen – REST-API verwendet GUIDs, nicht Katalognamen |
Program.cs |
Update — Registrieren TokenService und IHttpClientFactory; Aktualisieren der Route |
appsettings.json |
Vereinfachen — nur Dienstprinzipal-Anmeldeinformationen; XMLA-Konfiguration entfernen |
.csproj |
Update – ADOMD-Paket entfernen; hinzufügen Apache.Arrow und Microsoft.Identity.Client |
Bereinigen von Ressourcen
Wenn Sie mit dem Testen fertig sind:
- Beenden Sie den lokalen Dienst (drücken Sie STRG+C im Terminal).
- Wenn Sie eine Microsoft Entra App-Registrierung ausschließlich für dieses Lernprogramm erstellt haben, navigieren Sie zum portal Azure und löschen Sie sie.
- Entfernen Sie den Dienstprinzipal aus dem Power BI-Arbeitsbereich, wenn er nicht mehr benötigt wird.