Del via


Avanceret trinvis opdatering og data i realtid med XMLA-slutpunktet

Semantiske modeller i en Premium-kapacitet med XMLA-slutpunktet aktiveret til læse-/skrivehandlinger giver mulighed for mere avanceret opdatering, partitionsadministration og udrulninger af metadata via værktøjs-, script- og API-understøttelse. Derudover er opdateringshandlinger via XMLA-slutpunktet ikke begrænset til 48 opdateringer pr. dag, og tidsgrænsen for planlagt opdatering pålægges ikke.

Partitioner

Partitioner for semantiske modeltabeller er ikke synlige og kan ikke administreres ved hjælp af Power BI Desktop eller Power BI-tjeneste. For modeller i et arbejdsområde, der er tildelt en Premium-kapacitet, kan partitioner administreres via XMLA-slutpunktet. Du kan bruge værktøjer som SQL Server Management Studio (SSMS) eller open source Tabular Editor til at administrere partitioner via scripting med Tabular Model Scripting Language (TMSL) og programmatisk med Tabular Object Model (TOM).

Når du første gang publicerer en model til Power BI-tjeneste, har hver tabel i den nye model én partition. For tabeller uden politik for trinvis opdatering indeholder den ene partition alle rækker med data for den pågældende tabel, medmindre der anvendes filtre. For tabeller med en politik for trinvis opdatering findes den første partition kun, fordi Power BI ikke har anvendt politikken endnu. Du konfigurerer den første partition i Power BI Desktop, når du definerer filteret for dato/klokkeslætsinterval for din tabel baseret på parametrene RangeStart og RangeEnd og eventuelle andre filtre, der anvendes i Power Query-editor. Denne indledende partition indeholder kun de rækker med data, der opfylder dine filterkriterier.

Når du udfører den første opdateringshandling, opdaterer tabeller uden politik for trinvis opdatering alle rækker, der er indeholdt i tabellens enkelt standardpartition. For tabeller med en politik for trinvis opdatering oprettes der automatisk opdateringspartitioner og historiske partitioner, og rækker indlæses i dem i henhold til dato/klokkeslæt for hver række. Hvis politikken for trinvis opdatering omfatter hentning af data i realtid, føjer Power BI også en DirectQuery-partition til tabellen.

Vigtigt

Når du bruger trinvis opdatering med data i realtid (hybridtilstand), skal tabeller, der er relateret til hybridtabellen, bruge dobbelt lagertilstand for at undgå ydeevnesanktioner. Derudover kan cachelagring af visualiseringer forsinke liveopdateringer, indtil visualiseringer forespørger dataene igen. Du kan få flere oplysninger under Fejlfinding af trinvis opdatering og data i realtid.

Denne første opdateringshandling kan tage et stykke tid, afhængigt af mængden af data, der skal indlæses fra datakilden. Modellens kompleksitet kan også være en væsentlig faktor, fordi opdateringshandlinger skal udføre mere behandling og genberegning. Denne handling kan startes. Du kan finde flere oplysninger under Undgå timeout ved den første fulde opdatering.

Partitioner oprettes for og navngives efter periodegranularitet: År, kvartaler, måneder og dage. De nyeste partitioner, opdateringspartitionerne , indeholder rækker i den opdateringsperiode, du angiver i politikken. Historiske partitioner indeholder rækker efter hele perioden op til opdateringsperioden. Hvis realtid er aktiveret, henter en DirectQuery-partition eventuelle dataændringer, der er opstået efter slutdatoen for opdateringsperioden. Granulariteten for opdatering og historiske partitioner afhænger af de opdaterings- og historiske perioder (lager), du vælger, når du definerer politikken.

Hvis dags dato f.eks. er den 2. februar 2021, og vores FactInternetSales-tabel i datakilden indeholder rækker op til i dag, hvis vores politik angiver at inkludere ændringer i realtid, opdatere rækker i den seneste opdateringsperiode på én dag og gemme rækker i den seneste tre års historiske periode. Med den første opdateringshandling oprettes der derefter en DirectQuery-partition til ændringer i fremtiden. Der oprettes en ny importpartition for dagens rækker, og der oprettes en historisk partition for i går, en heldagsperiode, 1. februar 2021. Der oprettes en historisk partition for den foregående hele månedsperiode (januar 2021). Der oprettes en historisk opdeling for den foregående helårsperiode (2020). Og der oprettes historiske opdelinger for 2019 og 2018 helårsperioder. Der oprettes ingen partitioner for hele kvartaler, fordi det første hele kvartal af 2021 endnu ikke er afsluttet den 2. februar.

Diagrammet viser partitionsnavngivningsgranulariteten, der er beskrevet i teksten.

Ved hver opdateringshandling opdateres kun partitionerne for opdateringsperioden. Datofilteret for DirectQuery-partitionen opdateres, så det kun omfatter de ændringer, der sker efter den aktuelle opdateringsperiode. Der oprettes en ny opdateringspartition for nye rækker med en ny dato/klokkeslæt inden for den opdaterede opdateringsperiode. Eksisterende rækker med en dato/et klokkeslæt, der allerede er inden for eksisterende partitioner i opdateringsperioden, opdateres med opdateringer. Rækker med en dato/et klokkeslæt, der er ældre end opdateringsperioden, opdateres ikke længere.

Når hele perioder lukkes, flettes skillevægge. Hvis der f.eks. er angivet en opdateringsperiode på én dag og en historisk lagerperiode på tre år i politikken, flettes alle dagspartitioner for den forrige måned til en månedspartition på den første dag i måneden. På den første dag i et nyt kvartal flettes alle tre foregående månedspartitioner til en kvartalspartition. På den første dag i et nyt år flettes alle fire foregående kvartalspartitioner til en årsdeling.

En model bevarer altid partitioner for hele den historiske lagerperiode plus hele periodepartitioner op til den aktuelle opdateringsperiode. I eksemplet bevares hele tre års historiske data i partitioner for 2018, 2019, 2020 og også partitioner for månedsperioden 2021K101, dagsperioden 2021Q10201 og partitionen for opdateringsperioden for den aktuelle dag. Da eksemplet bevarer historiske data i tre år, bevares 2018-partitionen indtil den første opdatering den 1. januar 2022.

Med trinvis opdatering af Power BI og data i realtid håndterer tjenesten partitionsadministrationen for dig baseret på politikken. Tjenesten kan håndtere al partitionsadministration for dig, men ved hjælp af værktøjer via XMLA-slutpunktet kan du selektivt opdatere partitioner individuelt, sekventielt eller parallelt.

Almindelige skabeloner til opdatering af partitioner

Når du arbejder med XMLA-slutpunktshandlinger, skal du overveje disse almindelige mønstre til administration af opdateringshandlinger:

  • Hyppige små opdateringer: Kør flere små, målrettede opdateringshandlinger i åbningstiden ved hjælp af XMLA-partitionskommandoer eller den forbedrede REST API for at holde de seneste data opdaterede uden at behandle hele tabellen.
  • Selektive historiske backfills: Udfør større opdateringer af historiske partitioner eller engangsdatarettelser uden for arbejdstiden ved hjælp af TMSL med applyRefreshPolicy: false til at genopbygge specifikke historiske perioder uden at påvirke den automatiske politikfunktion.
  • Trinvise indledende indlæsninger: I store historiske perioder kan du opdele den indledende opdatering i mindre batches ved at behandle partitioner trinvist for at undgå timeout og administrere ressourceforbrug.

Disse mønstre giver dig mulighed for at balancere dataaktualitet i realtid med systemets ydeevne og ressourcebegrænsninger.

Opdateringsadministration med SQL Server Management Studio

SQL Server Management Studio (SSMS) kan bruges til at få vist og administrere partitioner, der er oprettet ved anvendelse af politikker for trinvis opdatering. Ved hjælp af SSMS kan du f.eks. opdatere en bestemt historisk partition, der ikke er i den trinvise opdateringsperiode, for at udføre en tilbagedateret opdatering uden at skulle opdatere alle historiske data. SSMS kan også bruges ved bootstrapping til at indlæse historiske data for store modeller ved trinvist at tilføje/opdatere historiske partitioner i batches.

Skærmbillede af vinduet Partitioner i SSMS.

Tilsidesæt funktionsmåden for trinvis opdatering

Med SSMS har du også mere kontrol over, hvordan du aktiverer opdateringer ved hjælp af Tabular Model Scripting Language og Tabular Object Model. I SSMS skal du f.eks. i Object Explorer højreklikke på en tabel og derefter vælge menupunktet Behandl tabel og derefter vælge knappen Script for at generere en TMSL-opdateringskommando.

Skærmbillede af knappen Script i dialogboksen Procestabel.

Disse parametre kan bruges sammen med TMSL-opdateringskommandoen til at tilsidesætte standardadfærden for trinvis opdatering:

  • applyRefreshPolicy. Hvis en tabel har defineret en politik for trinvis opdatering, bestemmer den, applyRefreshPolicy om politikken anvendes eller ej. Hvis politikken ikke anvendes, efterlader en fuld proceshandling partitionsdefinitioner uændrede, og alle partitioner i tabellen opdateres fuldt ud. Standardværdien er true.

  • ikrafttrædelsesdato. Hvis der anvendes en politik for trinvis opdatering, skal den kende dags dato for at bestemme rullende vinduesintervaller for den trinvise opdatering og historiske perioder. Parameteren effectiveDate giver dig mulighed for at tilsidesætte den aktuelle dato. Denne parameter er nyttig til test, demoer og forretningsscenarier, hvor data opdateres trinvist op til en dato i fortiden eller fremtiden, f.eks. budgetter i fremtiden. Standardværdien er dags dato.

{ 
  "refresh": {
    "type": "full",

    "applyRefreshPolicy": true,
    "effectiveDate": "12/31/2013",

    "objects": [
      {
        "database": "IR_AdventureWorks", 
        "table": "FactInternetSales" 
      }
    ]
  }
}

Du kan få mere at vide om tilsidesættelse af standardfunktionsmåden for trinvis opdatering med TMSL under Kommandoen Opdater.

Administration af politikker med Tabular Editor

Ud over SSMS kan du bruge Tabeleditor til at oprette og ændre politikker for trinvis opdatering direkte i forhold til semantiske modeller via XMLA-slutpunktet. Denne metode giver dig mulighed for at justere politikindstillinger – f.eks. opdateringsperioder, historiske perioder og kildeudtryk – uden at skulle publicere modellen igen fra Power BI Desktop. Tabeleditor kan også bruges til at anvende opdateringspolitikker på eksisterende tabeller og administrere RangeStart og RangeEnd parameterudtryk. Du kan finde flere oplysninger under Trinvis opdatering i dokumentationen til Tabular Editor.

Opdater orkestrering og automatisering

Ud over at bruge SSMS, TMSL og TOM til at administrere opdateringer via XMLA-slutpunktet. Du kan også orkestrere opdateringshandlinger for semantiske modeller ved hjælp af Power BI REST API. Den forbedrede opdaterings-API giver flere funktioner, herunder opdatering på tabelniveau og partitionsniveau, logik for nye forsøg, annullering og brugerdefineret timeoutstyring. Denne fremgangsmåde er nyttig til at integrere opdateringshandlinger i automatiserede arbejdsprocesser og CI/CD-pipelines. Du kan finde en detaljeret vejledning under Forbedret opdatering med Power BI REST API.

Sikring af optimal ydeevne

Med hver opdateringshandling kan Power BI-tjeneste sende initialiseringsforespørgsler til datakilden for hver trinvis opdateringspartition. Du kan muligvis forbedre ydeevnen for trinvis opdatering ved at reducere antallet af initialiseringsforespørgsler ved at sikre følgende konfiguration:

  • Den tabel, du konfigurerer trinvis opdatering for, skal hente data fra en enkelt datakilde. Hvis tabellen henter data fra mere end én datakilde, ganges antallet af forespørgsler, der sendes af tjenesten for hver opdateringshandling, med antallet af datakilder, hvilket potentielt reducerer ydeevnen for opdatering. Sørg for, at forespørgslen for den trinvise opdateringstabel er for en enkelt datakilde.
  • For løsninger med både trinvis opdatering af importpartitioner og realtidsdata med Direct Query skal alle partitioner forespørge på data fra en enkelt datakilde.
  • Hvis dine sikkerhedskrav tillader det, skal du angive indstillingen Niveau for beskyttelse af personlige oplysninger for datakilde til Organisation eller Offentlig. Som standard er privatniveauet Privat. Dette niveau kan dog forhindre data i at blive udvekslet med andre cloudkilder. Hvis du vil angive niveauet for beskyttelse af personlige oplysninger, skal du vælge menuen Flere indstillinger og derefter vælge Indstillinger>Legitimationsoplysninger> for datakildeRediger indstilling for legitimationsoplysninger>Indstilling for niveau for beskyttelse af personlige oplysninger for denne datakilde. Hvis niveauet for beskyttelse af personlige oplysninger er angivet i Power BI Desktop-modellen, før du publicerer til tjenesten, overføres det ikke til tjenesten, når du publicerer. Du skal stadig angive den i indstillingerne for semantisk model i tjenesten. Du kan få mere at vide under Niveauer for beskyttelse af personlige oplysninger.
  • Hvis du bruger en datagateway i det lokale miljø, skal du sørge for, at du bruger version 3000.77.3 eller nyere.

Undgå timeout ved første fulde opdatering

Når du har publiceret til Power BI-tjeneste, opretter den indledende fulde opdateringshandling for modellen partitioner for den trinvise opdateringstabel, indlæser og behandler historiske data for hele den periode, der er defineret i politikken for trinvis opdatering. For nogle modeller, der indlæser og behandler store mængder data, kan den tid, den indledende opdateringshandling tager, overskride den tidsgrænse for opdatering, der er pålagt af tjenesten, eller en tidsgrænse for forespørgsler, der er pålagt af datakilden.

Bootstrapping af den indledende opdateringshandling gør det muligt for tjenesten at oprette partitionsobjekter til den trinvise opdateringstabel, men ikke indlæse og behandle historiske data i nogen af partitionerne. SSMS bruges derefter til selektivt at behandle partitioner. Afhængigt af mængden af data, der skal indlæses for hver partition, kan du behandle hver partition sekventielt eller i små batches. Denne metode reducerer risikoen for, at en eller flere af disse partitioner forårsager en timeout. Følgende metoder fungerer for alle datakilder.

Anvend opdateringspolitik

Open source Tabular Editor 2-værktøjet giver en nem måde at starte en indledende opdateringshandling på. Når du har publiceret en model med en politik for trinvis opdatering, der er defineret for den fra Power BI Desktop til tjenesten, skal du oprette forbindelse til modellen ved hjælp af XMLA-slutpunktet i læse-/skrivetilstand. Kør Anvend opdateringspolitik på den trinvise opdateringstabel. Når kun politikken anvendes, oprettes partitioner, men der indlæses ingen data i dem. Opret derefter forbindelse til SSMS for at opdatere partitionerne sekventielt eller i batches for at indlæse og behandle dataene. Du kan finde flere oplysninger under Trinvis opdatering i dokumentationen til tabeleditoren.

Skærmbilledet viser tabeleditoren med Anvend opdateringspolitik valgt.

Power Query-filter til tomme partitioner

Før du publicerer modellen til tjenesten, skal du i Power Query-editor føje et andet filter til den ProductKey kolonne, der filtrerer andre værdier end 0 fra, effektivt eller filtrerer alle data fra tabellen FactInternetSales .

Skærmbilledet viser Power Query-editor med kode, der filtrerer produktnøglen fra.

Når du har valgt Luk og anvend i Power Query-editor, defineret politikken for trinvis opdatering og gemt modellen, publiceres modellen til tjenesten. Fra tjenesten køres den første opdateringshandling på modellen. Partitioner til tabellen FactInternetSales oprettes i henhold til politikken, men der indlæses og behandles ingen data, fordi alle data filtreres fra.

Når den første opdateringshandling er fuldført, fjernes det andet filter i ProductKey kolonnen tilbage i Power Query-editor. Når du har valgt Luk og anvend i Power Query-editor og gemt modellen, publiceres modellen ikke igen. Hvis modellen publiceres igen, overskriver den politikindstillingerne for trinvis opdatering og gennemtvinger en fuld opdatering af modellen, når der udføres en efterfølgende opdateringshandling fra tjenesten. Udfør i stedet en udrulning kun af metadata ved hjælp af ALM-værktøjssættet (Application Lifecycle Management), der fjerner filteret ProductKey på kolonnen fra modellen. SSMS kan derefter bruges til selektivt at behandle partitioner. Når alle partitioner er fuldt behandlet, som skal omfatte en procesgenberegning på alle partitioner, fra SSMS, opdaterer efterfølgende opdateringshandlinger på modellen fra tjenesten kun de trinvise opdateringspartitioner.

Tips

Sørg for at se videoer, blogs og meget mere, der leveres af Power BI's community af BI-eksperter.

Du kan få mere at vide om behandling af tabeller og partitioner fra SSMS under Behandle database, tabeller eller partitioner (Analysis Services). Du kan få mere at vide om behandling af modeller, tabeller og partitioner ved hjælp af TMSL under Opdater kommando (TMSL).

Brugerdefinerede forespørgsler til registrering af dataændringer

TMSL og TOM kan bruges til at tilsidesætte de registrerede dataændringers adfærd. Denne metode kan bruges til at undgå at bevare kolonnen med den seneste opdatering i cachen i hukommelsen. Det kan også aktivere scenarier, hvor en konfigurations- eller instruktionstabel forberedes af ETL-processer (udtræk, transformering og indlæsning). Giver dig mulighed for kun at markere de partitioner, der skal opdateres. Denne metode kan skabe en mere effektiv trinvis opdateringsproces, hvor kun de påkrævede perioder opdateres, uanset hvor længe siden dataopdateringer fandt sted.

Det pollingExpression er beregnet til at være et let M-udtryk eller navn på en anden M-forespørgsel. Den skal returnere en skalarværdi og udføres for hver partition. Hvis den returnerede værdi er forskellig fra, hvad den var, sidste gang der skete en trinvis opdatering, markeres partitionen til fuld behandling.

Følgende eksempel dækker alle 120 måneder i den historiske periode for ændringer med tilbagevirkende kraft. Hvis du angiver 120 måneder i stedet for 10 år, betyder det, at datakomprimering muligvis ikke er så effektiv. Det undgår dog at skulle opdatere et helt historisk år, hvilket ville være dyrere, når en måned ville være tilstrækkelig til en tilbagedateret ændring.

"refreshPolicy": {
    "policyType": "basic",
    "rollingWindowGranularity": "month",
    "rollingWindowPeriods": 120,
    "incrementalGranularity": "month",
    "incrementalPeriods": 120,
    "pollingExpression": "<M expression or name of custom polling query>",
    "sourceExpression": [
    "let ..."
    ]
}

Tips

Sørg for at se videoer, blogs og meget mere, der leveres af Power BI's community af BI-eksperter.

Udrulning kun af metadata

Når du publicerer en ny version af en .pbix-fil fra Power BI Desktop til et arbejdsområde. Du får vist følgende meddelelse om at erstatte den eksisterende model, hvis der allerede findes en model med samme navn.

Skærmbilledet viser dialogboksen Erstat model.

I nogle tilfælde vil du måske ikke erstatte modellen, især med trinvis opdatering. Modellen i Power BI Desktop kan være betydeligt mindre end den i Power BI-tjeneste. Hvis modellen i Power BI-tjeneste har en politik for trinvis opdatering, kan du miste flere års historiske data, hvis modellen udskiftes. Opdatering af alle historiske data kan tage timer og resultere i systemnedetid for brugerne.

I stedet er det bedre at udføre en implementering kun af metadata, som tillader implementering af nye objekter uden at miste de historiske data. Hvis du f.eks. kun tilføjer nogle få målinger, kan du kun udrulle de nye målinger uden at skulle opdatere dataene, hvilket sparer tid.

For arbejdsområder, der er tildelt en Premium-kapacitet, der er konfigureret til XMLA-slutpunkt læse/skrive, aktiverer kompatible værktøjer kun udrulning af metadata. ALM Toolkit er f.eks. et skemadiff-værktøj til Power BI-modeller og kan kun bruges til at udføre udrulning af metadata.

Download og installer den nyeste version af ALM Toolkit fra Analysis Services Git-lageret. Trinvis vejledning til brug af ALM Toolkit er ikke inkluderet i Microsoft-dokumentationen. ALM Toolkit-dokumentationslinks og oplysninger om understøttelse er tilgængelige på båndet Hjælp . Hvis du vil udføre en udrulning af metadata, skal du udføre en sammenligning og vælge den kørende Power BI Desktop-forekomst som kilde og den eksisterende model i Power BI-tjeneste som destination. Overvej de viste forskelle, og spring over opdateringen af tabellen med trinvise opdateringspartitioner, eller brug dialogboksen Indstillinger til at bevare partitioner til tabelopdateringer. Valider markeringen for at sikre destinationsmodellens integritet, og opdater derefter.

Skærmbilledet viser vinduet ALM Toolkit.

Tilføjelse af en politik for trinvis opdatering og data i realtid programmatisk

Du kan også bruge TMSL og TOM til at føje en politik for trinvis opdatering til en eksisterende model via XMLA-slutpunktet.

Notat

Hvis du vil undgå kompatibilitetsproblemer, skal du sørge for at bruge den nyeste version af Analysis Services-klientbibliotekerne. Hvis du f.eks. vil arbejde med hybridpolitikker, skal versionen være 19.27.1.8 eller nyere.

Processen omfatter følgende trin:

  1. Sørg for, at destinationsmodellen har det påkrævede minimumskompatibilitetsniveau. I SSMS skal du højreklikke på [modelnavn]>Egenskaber>Kompatibilitetsniveau. Hvis du vil øge kompatibilitetsniveauet, skal du enten bruge et createOrReplace TMSL-script eller kontrollere følgende TOM-eksempelkode for et eksempel.

    a. Import policy - 1550
    b. Hybrid policy - 1565
    
  2. Føj parametrene RangeStart og RangeEnd til modeludtrykkene. Hvis det er nødvendigt, kan du også tilføje en funktion til at konvertere dato/klokkeslætsværdier til datotaster.

  3. Definer et RefreshPolicy objekt med den ønskede arkivering (rullende vindue) og trinvise opdateringsperioder samt et kildeudtryk, der filtrerer måltabellen baseret på parametrene RangeStart og RangeEnd . Angiv opdateringspolitiktilstanden til Import eller Hybrid afhængigt af dine datakrav i realtid. Hybrid får Power BI til at føje en DirectQuery-partition til tabellen for at hente de seneste ændringer fra den datakilde, der fandt sted efter det seneste opdateringstidspunkt.

  4. Føj opdateringspolitikken til tabellen, og udfør en fuld opdatering, så Power BI partitionerer tabellen i henhold til dine behov.

Følgende kodeeksempel viser, hvordan du udfører de forrige trin ved hjælp af TOM. Hvis du vil bruge dette eksempel, som det er, skal du have en kopi til AdventureWorksDW-databasen og importere tabellen FactInternetSales til en model. Kodeeksemplet antager, at parametrene RangeStartRangeEnd og DateKey funktionen ikke findes i modellen. Du skal blot importere tabellen FactInternetSales og publicere modellen til et arbejdsområde på Power BI Premium. Opdater derefter, workspaceUrl så kodeeksemplet kan oprette forbindelse til din model. Opdater eventuelle flere kodelinjer efter behov.

using System;
using TOM = Microsoft.AnalysisServices.Tabular;
namespace Hybrid_Tables
{
    class Program
    {
        static string workspaceUrl = "<Enter your Workspace URL here>";
        static string databaseName = "AdventureWorks";
        static string tableName = "FactInternetSales";
        static void Main(string[] args)
        {
            using (var server = new TOM.Server())
            {
                // Connect to the dataset.
                server.Connect(workspaceUrl);
                TOM.Database database = server.Databases.FindByName(databaseName);
                if (database == null)
                {
                    throw new ApplicationException("Database cannot be found!");
                }
                if(database.CompatibilityLevel < 1565)
                {
                    database.CompatibilityLevel = 1565;
                    database.Update();
                }
                TOM.Model model = database.Model;
                // Add RangeStart, RangeEnd, and DateKey function.
                model.Expressions.Add(new TOM.NamedExpression {
                    Name = "RangeStart",
                    Kind = TOM.ExpressionKind.M,
                    Expression = "#datetime(2021, 12, 30, 0, 0, 0) meta [IsParameterQuery=true, Type=\"DateTime\", IsParameterQueryRequired=true]"
                });
                model.Expressions.Add(new TOM.NamedExpression
                {
                    Name = "RangeEnd",
                    Kind = TOM.ExpressionKind.M,
                    Expression = "#datetime(2021, 12, 31, 0, 0, 0) meta [IsParameterQuery=true, Type=\"DateTime\", IsParameterQueryRequired=true]"
                });
                model.Expressions.Add(new TOM.NamedExpression
                {
                    Name = "DateKey",
                    Kind = TOM.ExpressionKind.M,
                    Expression =
                        "let\n" +
                        "    Source = (x as datetime) => Date.Year(x)*10000 + Date.Month(x)*100 + Date.Day(x)\n" +
                        "in\n" +
                        "    Source"
                });
                // Apply a RefreshPolicy with Real-Time to the target table.
                TOM.Table salesTable = model.Tables[tableName];
                TOM.RefreshPolicy hybridPolicy = new TOM.BasicRefreshPolicy
                {
                    Mode = TOM.RefreshPolicyMode.Hybrid,
                    IncrementalPeriodsOffset = -1,
                    RollingWindowPeriods = 1,
                    RollingWindowGranularity = TOM.RefreshGranularityType.Year,
                    IncrementalPeriods = 1,
                    IncrementalGranularity = TOM.RefreshGranularityType.Day,
                    SourceExpression =
                        "let\n" +
                        "    Source = Sql.Database(\"demopm.database.windows.net\", \"AdventureWorksDW\"),\n" +
                        "    dbo_FactInternetSales = Source{[Schema=\"dbo\",Item=\"FactInternetSales\"]}[Data],\n" +
                        "    #\"Filtered Rows\" = Table.SelectRows(dbo_FactInternetSales, each [OrderDateKey] >= DateKey(RangeStart) and [OrderDateKey] < DateKey(RangeEnd))\n" +
                        "in\n" +
                        "    #\"Filtered Rows\""
                };
                salesTable.RefreshPolicy = hybridPolicy;
                model.RequestRefresh(TOM.RefreshType.Full);
                model.SaveChanges();
            }
            Console.WriteLine("{0}{1}", Environment.NewLine, "Press [Enter] to exit...");
            Console.ReadLine();
        }
    }
}