Vejledning: Byg en .NET mid-tier service med Execute DAX Queries REST API'en

I denne tutorial tager du Microsoft. Samples.XMLA.ExecuteQueries sample — et .NET Web API, der proxysender DAX-forespørgsler gennem XMLA-endpointet ved hjælp af ADOMD.NET — og modificerer det til at bruge Execute DAX Queries REST API, som returnerer resultater i Apache Arrow IPC-format. Eksemplaret giver mid-tier rammen (routing, rate limiting, health probe). Denne vejledning viser dig, hvordan du erstatter XMLA/ADOMD-forespørgselsudførelses-plumbing med REST API-kald og Arrow IPC-responshåndtering.

Forudsætninger

  • .NET 8 SDK eller nyere.
  • Et Power BI-arbejdsområde på Premium- eller Fabric-kapacitet med mindst én semantisk model.
  • En Microsoft Entra-appregistrering med en klienthemmelighed.
  • Servicehovedpersonen tilføjet som workspace-medlem med rollen Bidragyder (eller højere).
  • Følgende lejerindstillinger aktiveret:
    • Dataset Execute Queries REST API og Tillad serviceprincipaler at bruge Power BI API'er (under Developer settings).
    • Tillad XMLA-endepunkter og analyser i Excel med on-premises semantiske modeller (under Integrationsindstillinger).

For detaljer om eksempel-servicearkitekturen, se eksempel README.

Før du begynder

Eksempeltjenesten bruger XMLA-endpointet med ADOMD.NET. Denne vejledning konverterer den til at bruge Execute DAX Queries REST API, som returnerer resultater i Apache Arrow IPC-format. Begge tilgange lader dig køre DAX-forespørgsler mod Power BI-semantiske modeller, men de adskiller sig på vigtige måder.

XMLA / ADOMD.NET Execute DAX Queries REST API
Protokollen XMLA over HTTPS (proprietær binærfil) Standard HVILE (HTTP POST / svar)
Klientbibliotek Microsoft.AnalysisServices.AdomdClient — Windows-orienteret (.NET Core-pakke tilgængelig, men begrænset cross-platform support), administrerer sessioner og forbindelser HttpClient + Apache.Arrow — letvægts, platformoverskridende, tilstandsløs
Godkendelse Forbindelsesstreng med adgangstoken; Sessioner på forbindelsesniveau Bærertoken pr. anmodning; ingen sessionstilstand
Svarformat Tabular rowsets parset af ADOMD-klientbiblioteket Apache Arrow IPC — et kolonneformat med bredt økosystemunderstøttelse (Python, R, Spark, DuckDB)
Forbindelsesstyring Kræver pooling for at amortisere sessionsopsætningsomkostninger Tilstandsløs HTTP — ingen pooling nødvendig; MSAL håndterer token-caching
Bedst til Legacy-integrationer, MDX-forespørgsler, fintgået sessionskontrol Nye tjenester, hvor du ønsker en enklere HTTP-integration, kolonner ydeevne eller tværsprogede forbrugere

Vælg Execute DAX Queries REST API når du bygger en ny tjeneste, eller dine downstream-forbrugere kan drage fordel af Arrow IPC (for eksempel analysepipelines, Python notebooks eller kolonnedatabaser). Behold XMLA/ADOMD, hvis du har brug for MDX-understøttelse, eller stol på sessionsniveau-funktioner som beregnede medlemmer begrænset til en session.

1 - Klon og verificér prøven

Klon repositoryet og bekræft, at det kompilerer:

git clone https://github.com/dbrownems/Microsoft.Samples.XMLA.ExecuteQueries.git
cd Microsoft.Samples.XMLA.ExecuteQueries
dotnet build

Løsningen indeholder to projekter: mid-tier service (Microsoft.Samples.XMLA.ExecuteQueries) og en load test-klient (Tester). Du behøver ikke køre den oprindelige service mod et live workspace — bare verificér, at buildet lykkes, før du laver ændringer.

2 - Opdater NuGet-afhængigheder

I projektet Microsoft.Samples.XMLA.ExecuteQueries fjernes ADOMD.NET-pakken og tilføjes pakker til Arrow API'en:

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

Behold Microsoft.PowerBI.Api-pakken, hvis du vil genbruge dens anmodnings-/svarmodeltyper; ellers fjern det og definer dine egne DTO'er.

3 - Erstat ADOMD-forbindelsespooling med MSAL-token-caching

Eksemplet bruges AdomdConnectionPool.cs til at samle XMLA-forbindelser. Arrow API'en er et stateless REST-endpoint, så du erstatter connection pooling med MSAL-token-caching.

Opret en ny fil 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 cacher tokens automatisk — efterfølgende opkald returnerer det cachede token, indtil det udløber.

Slet AdomdConnectionPool.cs og AdomdExtensions.cs. De er ikke længere nødvendige.

4 - Opdater forespørgselshåndtereren til at kalde Arrow API'en

I Handlers.cs, erstatter ADOMD-forespørgselsudførelsen med et HTTP-kald til Execute DAX Queries-endpointet.

Fjern alle ADOMD-referencer (AdomdConnectionPool, AdomdConnection, AdomdCommand, WrappedConnection). Skift handlerens injicerede afhængigheder til og HttpClient i stedet for TokenService forbindelsespools og workspace-opslag.

Byg REST API URL ud fra arbejdsområdet og datasætets GUID'er, der allerede er tilgængelige i ruteparametrene:

var url = $"https://api.powerbi.com/v1.0/myorg/groups/{workspaceId}"
        + $"/datasets/{datasetId}/executeDaxQueries";

POST DAX-forespørgslen med en JSON-anmodningskrop:

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();

Brug HttpCompletionOption.ResponseHeadersRead sådan, at responskroppen streamer uden buffering — det er vigtigt for store resultatsæt.

5 - Håndter Arrow IPC-responsen

Execute DAX Queries API returnerer en eller flere Arrow IPC-strømme, der er sammenkædet i svarkroppen. Hver strøm indeholder skemametadata, der angiver dens formål:

  • Dataresultat — forespørgselsresultaterne (ingen specielle metadataflag).
  • FejlresultatIsError=true i skemametadata, med FaultCode og FaultString værdier.
  • UdførelsesmålingerIsExecMetrics=true (hvis du har anmodet om målinger via parameteren executionMetrics ).

Erstat DataResult.cs med logik, der håndterer Arrow-responsen. Hvis din mid-tier blot videresender Arrow IPC til downstream-forbrugere, så stream bytes igennem uden deserialisering:

context.Response.ContentType = "application/vnd.apache.arrow.stream";
await response.Content.CopyToAsync(context.Response.Body);

Hvis du skal inspicere resultater eller konvertere formater, skal du deserialisere Arrow-strømmen med 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.
}

Tjek skemametadata for at opdage fejlsvar:

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 - Forenkle konfigurationen af arbejdsområder

Eksemplaret appsettings.json konfigurerer XMLA-endpoints og opslag efter datasætnavne, fordi ADOMD forbinder via katalognavn. Arrow REST API bruger workspace- og datasæt-GUID'er direkte fra anmodnings-URL'en, så konfigurationen er enklere.

Opdater appsettings.json med dine serviceprincipal-oplysninger og fjern de XMLA-specifikke felter:

{
  "PowerBI": {
    "TenantId": "YOUR_TENANT_ID",
    "ClientId": "YOUR_APP_CLIENT_ID",
    "ClientSecret": "YOUR_CLIENT_SECRET"
  }
}

Sektionen Workspaces med XmlaEndpoint og Datasets arrays er ikke længere nødvendig. Du kan slette Workspace.cs og Dataset.cs, eller genbruge Datasets listen som en tilladelsesliste til styring (hvilket begrænser, hvilke datasæt tjenesten kan forespørge).

7 - Registrer tjenester og opdater routing

I Program.cs, erstatter ADOMD-poolen og arbejdsområderegistreringerne med de nye tjenester:

builder.Services.AddSingleton<TokenService>();
builder.Services.AddHttpClient();

Opdater ruten, så den matcher Execute DAX Queries endpoint-mønsteret:

app.MapPost(
    "/v1.0/myorg/groups/{workspaceId:Guid}"
    + "/datasets/{datasetId:Guid}/executeDaxQueries",
    Handlers.ExecuteDaxQueriesInGroup);

Den eksisterende hastighedsbegrænser, sundhedsprobe og anmodningstæller fra prøven forbliver nyttige as-is.

8 - Test tjenesten

Kør tjenesten:

dotnet run --project Microsoft.Samples.XMLA.ExecuteQueries

Send en DAX-forespørgsel fra en anden terminal:

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'\'')"}'

Svaret er en binær Arrow IPC-strøm. Gem det i en fil og inspicer med 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())
"

Sammendrag af ændringer

Original fil Handling
AdomdConnectionPool.cs Slet — erstattet af MSAL-token-caching i TokenService.cs
AdomdExtensions.cs Slet — JSON-streaminglogik er ikke længere nødvendig
DataResult.cs Omskriv — stream Arrow IPC igennem, eller deserialiser med ArrowStreamReader
Handlers.cs Omskrivning — HTTP POST til at udføre DAX Forespørgsler API i stedet for ADOMD-udførelse
Workspace.cs / Dataset.cs Forenkle eller slette — REST API bruger GUIDs, ikke katalognavne
Program.cs Opdater — registrer TokenService og IHttpClientFactory; opdater ruten
appsettings.json Forenkle — kun tjenesteprincipal-legitimation; Fjern XMLA-konfigurationen
.csproj Update — fjern ADOMD-pakken; tilføj Apache.Arrow og Microsoft.Identity.Client

Ryd op i ressourcer

Når du er færdig med at teste:

  1. Stop den lokale service (tryk Ctrl+C i terminalen).
  2. Hvis du har oprettet en Microsoft Entra app-registrering udelukkende til denne tutorial, skal du gå til portalen Azure og slette den.
  3. Fjern serviceprincipalen fra Power BI-arbejdsområdet, hvis den ikke længere er nødvendig.