TripPin bölüm 10 - Temel sorguyu katlama

Bu çok bölümlü öğretici, Power Query için yeni bir veri kaynağı uzantısı oluşturmayı kapsar. Öğreticinin sırayla yapılması amaçlanır; her ders önceki derslerde oluşturulan bağlayıcı üzerinde oluşturulur ve bağlayıcınıza artımlı olarak yeni özellikler ekler.

Bu derste şunları yapacaksınız:

  • Sorguyu kaynağa döndürmenin temellerini öğrenin
  • Table.View işlevi hakkında bilgi edinin
  • OData sorguyu katlama işleyicilerini çoğaltma:
  • $top
  • $skip
  • $count
  • $select
  • $orderby

M dilinin güçlü özelliklerinden biri, dönüştürme çalışmalarını temel alınan bir veya daha fazla veri kaynağına gönderebilmesidir. Bu özellik Sorgu Katlama olarak adlandırılır (diğer araçlar/teknolojiler de Koşul Gönderme veya Sorgu Temsilcisi olarak benzer işleve başvurur).

OData.Feed veya Odbc.DataSource gibi yerleşik sorgu katlama özelliklerine sahip bir M işlevi kullanan özel bir bağlayıcı oluştururken bağlayıcınız bu özelliği otomatik olarak ücretsiz olarak devralır.

Bu öğretici, Table.View işlevi için işlev işleyicileri uygulayarak OData için yerleşik sorgu katlama davranışını çoğaltır. Öğreticinin bu bölümü, uygulanması daha kolay işleyicilerden bazılarını (ifade ayrıştırma ve durum izleme gerektirmeyen işleyiciler) uygular.

OData hizmetinin sunabileceği sorgu özellikleri hakkında daha fazla bilgi edinmek için OData v4 URL Kuralları'na gidin.

Not

Daha önce belirtildiği gibi, OData.Feed işlevi otomatik olarak sorgu katlama özellikleri sağlar. TripPin serisi OData hizmetini normal bir REST API olarak değerlendirdiğinden, OData.Feed yerine Web.Contents'i kullanarak sorguyu katlama işleyicilerini kendiniz uygulamanız gerekir. Gerçek dünya kullanımı için mümkün olduğunca OData.Feed kullanmanızı öneririz.

Sorguyu kaynağa döndürme hakkında daha fazla bilgi için Power Query'de sorgu değerlendirmesine ve sorguyu kaynağa döndürmeye genel bakış bölümüne gidin.

Table.View kullanma

Table.View işlevi, özel bağlayıcının veri kaynağınız için varsayılan dönüştürme işleyicilerini geçersiz kılmasına olanak tanır. Table.View uygulaması, desteklenen işleyicilerden biri veya daha fazlası için bir işlev sağlar. İşleyici engellenmemişse veya değerlendirme sırasında bir error döndürürse, M altyapısı varsayılan işleyicisine geri döner.

Özel bağlayıcı Web.Contents gibi örtük sorgu katlama desteği olmayan bir işlev kullandığında, varsayılan dönüştürme işleyicileri her zaman yerel olarak gerçekleştirilir. Bağlandığınız REST API sorgunun parçası olarak sorgu parametrelerini destekliyorsa Table.View, dönüştürme çalışmalarının hizmete gönderilmesini sağlayan iyileştirmeler eklemenize olanak tanır.

Table.View işlevi aşağıdaki imzaya sahiptir:

Table.View(table as nullable table, handlers as record) as table

Uygulamanız ana veri kaynağı işlevinizi sarmalar. Table.View için iki gerekli işleyici vardır:

  • GetType—sorgu sonucunun beklenen table type değerini verir
  • GetRows—veri kaynağı işlevinizin gerçek table sonucunu verir

En basit uygulama aşağıdaki örneğe benzer olacaktır:

TripPin.SuperSimpleView = (url as text, entity as text) as table =>
    Table.View(null, [
        GetType = () => Value.Type(GetRows()),
        GetRows = () => GetEntity(url, entity)
    ]);

TripPinNavTable işlevini yerine çağıracak TripPin.SuperSimpleViewGetEntityşekilde güncelleştirin:

withData = Table.AddColumn(rename, "Data", each TripPin.SuperSimpleView(url, [Name]), type table),

Birim testlerini yeniden çalıştırırsanız işlevinizin davranışının değiştirilmediğini görürsünüz. Bu durumda Table.View uygulamanız çağrısından GetEntitygeçer. Henüz herhangi bir dönüştürme işleyicisi (henüz) uygulamadığınız için özgün url parametreye dokunulmaz.

Table.View'un ilk uygulaması

Table.View'un yukarıdaki uygulaması basittir, ancak çok kullanışlı değildir. Aşağıdaki uygulama temeliniz olarak kullanılır; herhangi bir katlama işlevi uygulamaz, ancak bunu yapmanız gereken yapı iskelesine sahiptir.

TripPin.View = (baseUrl as text, entity as text) as table =>
    let
        // Implementation of Table.View handlers.
        //
        // We wrap the record with Diagnostics.WrapHandlers() to get some automatic
        // tracing if a handler returns an error.
        //
        View = (state as record) => Table.View(null, Diagnostics.WrapHandlers([
            // Returns the table type returned by GetRows()
            GetType = () => CalculateSchema(state),

            // Called last - retrieves the data from the calculated URL
            GetRows = () => 
                let
                    finalSchema = CalculateSchema(state),
                    finalUrl = CalculateUrl(state),

                    result = TripPin.Feed(finalUrl, finalSchema),
                    appliedType = Table.ChangeType(result, finalSchema)
                in
                    appliedType,

            //
            // Helper functions
            //
            // Retrieves the cached schema. If this is the first call
            // to CalculateSchema, the table type is calculated based on
            // the entity name that was passed into the function.
            CalculateSchema = (state) as type =>
                if (state[Schema]? = null) then
                    GetSchemaForEntity(entity)
                else
                    state[Schema],

            // Calculates the final URL based on the current state.
            CalculateUrl = (state) as text => 
                let
                    urlWithEntity = Uri.Combine(state[Url], state[Entity])
                in
                    urlWithEntity
        ]))
    in
        View([Url = baseUrl, Entity = entity]);

Table.View çağrısına bakarsanız, kaydınDiagnostics.WrapHandlers çevresinde handlers fazladan bir sarmalayıcı işlevi görürsünüz. Bu yardımcı işlevi Tanılama modülünde bulunur (tanılama dersini ekleme bölümünde sunulmuştur) ve tek tek işleyiciler tarafından ortaya çıkarılan hataları otomatik olarak izlemeniz için size yararlı bir yol sağlar.

GetType ve GetRows işlevleri, ve olmak üzere iki yeni yardımcı işleviCalculateSchemaCalculateUrlkullanacak şekilde güncelleştirilir. Şu anda bu işlevlerin uygulamaları oldukça basittir. İşlev tarafından daha önce yapılan işlemlerin parçalarını içerdiğine GetEntity dikkat edin.

Son olarak, parametre kabul eden bir iç işlev (View) tanımladığınıza state dikkat edin. Siz daha fazla işleyici uyguladığınızda, bunlar iç işlevi özyinelemeli olarak çağırır View , güncelleştirilir ve devam eder state .

TripPinNavTable işlevini bir kez daha güncelleştirin, çağrısı TripPin.SuperSimpleView yerine yeni TripPin.View işlev çağrısı yazın ve birim testlerini yeniden çalıştırın. Henüz yeni bir işlev görmezsiniz, ancak artık test için sağlam bir temele sahipsiniz.

Sorguyu katlama uygulama

Sorgu katlanamadığından M altyapısı otomatik olarak yerel işlemeye geri döndüğünden Table.View işleyicilerinizin düzgün çalıştığını doğrulamak için bazı ek adımlar atmalısınız.

Katlama davranışını el ile doğrulamanın yolu, Birim testlerinizin Fiddler gibi bir araç kullanarak gerçekleştirilen URL isteklerini izlemektir. Alternatif olarak, öğesine TripPin.Feed eklediğiniz tanılama günlüğü çalıştırılmakta olan tam URL'yi gösterir ve bu, işleyicilerinizin eklediği OData sorgu dizesi parametrelerini içermelidir.

Sorguyu kaynağa döndürmeyi doğrulamanın otomatik bir yolu, sorgu tamamen katlanmazsa birim testi yürütmenizin başarısız olmasını zorlamaktır. Bunu yapmak için proje özelliklerini açıp Katlama Hatası'nı True olarak ayarlayabilirsiniz. Bu ayar etkinleştirildiğinde, yerel işleme gerektiren tüm sorgular aşağıdaki hatayla sonuçlanır:

İfadeyi kaynağa katlayamadık. Lütfen daha basit bir ifade deneyin.

Bunu test etmek için birim test dosyanıza bir veya daha fazla tablo dönüştürmesi içeren yeni Fact bir dosya ekleyebilirsiniz.

// Query folding tests
Fact("Fold $top 1 on Airlines", 
    #table( type table [AirlineCode = text, Name = text] , {{"AA", "American Airlines"}} ), 
    Table.FirstN(Airlines, 1)
)

Not

Katlama Hatası hatası ayarı "tümü veya hiç" yaklaşımıdır. Birim testlerinizin bir parçası olarak katlanacak şekilde tasarlanmamış sorguları test etmek istiyorsanız, testleri uygun şekilde etkinleştirmek/devre dışı bırakmak için bazı koşullu mantık eklemeniz gerekir.

Bu öğreticinin kalan bölümlerinde her biri yeni bir Table.View işleyicisi ekler. Test Temelli Geliştirme (TDD) yaklaşımını benimsersiniz; burada ilk olarak başarısız birim testleri ekler ve sonra bunları çözmek için M kodunu uygularsınız.

Aşağıdaki işleyici bölümlerinde işleyici tarafından sağlanan işlevler, OData eşdeğeri sorgu söz dizimi, birim testleri ve uygulama açıklanmaktadır. Daha önce açıklanan yapı iskelesi kodunu kullanarak her işleyici uygulaması iki değişiklik gerektirir:

  • Kaydı güncelleştiren işleyiciyi Table.View'a state ekleme.
  • öğesinin değerlerini state almak için değiştirerek CalculateUrl url ve/veya sorgu dizesi parametrelerini ekleyin.

OnTake ile Table.FirstN İşleme

İşleyiciOnTake, içinden GetRowsalınacak en fazla satır sayısı olan bir count parametre alır. OData terimlerinde bunu $top sorgu parametresine çevirebilirsiniz.

Aşağıdaki birim testlerini kullanırsınız:

// Query folding tests
Fact("Fold $top 1 on Airlines", 
    #table( type table [AirlineCode = text, Name = text] , {{"AA", "American Airlines"}} ), 
    Table.FirstN(Airlines, 1)
),
Fact("Fold $top 0 on Airports", 
    #table( type table [Name = text, IataCode = text, Location = record] , {} ), 
    Table.FirstN(Airports, 0)
),

Bu testlerin her ikisi de table.firstn kullanarak sonuç kümesini ilk X satır sayısına göre ayarlar. Bu testleri Katlama Hatası ayarıyla False çalıştırırsanız (varsayılan), testler başarılı olmalıdır, ancak Fiddler çalıştırırsanız (veya izleme günlüklerini denetlerseniz), gönderdiğiniz isteğin OData sorgu parametresi içermediğini fark edin.

Tanılama izlemesi.

Katlama Hatası'nda Hata değerini olarak Trueayarlarsanız, testler hatayla Please try a simpler expression. başarısız olur. Bu hatayı düzeltmek için için OnTakeilk Table.View işleyicinizi tanımlamanız gerekir.

İşleyici OnTake aşağıdaki koda benzer:

OnTake = (count as number) =>
    let
        // Add a record with Top defined to our state
        newState = state & [ Top = count ]
    in
        @View(newState),

CalculateUrl İşlev, kayıttaki Topstate değeri ayıklamak ve sorgu dizesinde doğru parametreyi ayarlamak için güncelleştirilir.

// Calculates the final URL based on the current state.
CalculateUrl = (state) as text => 
    let
        urlWithEntity = Uri.Combine(state[Url], state[Entity]),

        // Uri.BuildQueryString requires that all field values
        // are text literals.
        defaultQueryString = [],

        // Check for Top defined in our state
        qsWithTop =
            if (state[Top]? <> null) then
                // add a $top field to the query string record
                defaultQueryString & [ #"$top" = Number.ToText(state[Top]) ]
            else
                defaultQueryString,

        encodedQueryString = Uri.BuildQueryString(qsWithTop),
        finalUrl = urlWithEntity & "?" & encodedQueryString
    in
        finalUrl

Birim testlerini yeniden çalıştırdığınızda, eriştiğiniz URL'nin şimdi parametresini içerdiğine $top dikkat edin. URL kodlaması $top nedeniyle olarak %24topgörünür, ancak OData hizmeti bunu otomatik olarak dönüştürecek kadar akıllıdır.

Üstte tanılama izlemesi.

Table.Skip'i OnSkip ile İşleme

İşleyici OnSkip çok benzer OnTake. Sonuç kümesinden atlanan satır sayısı olan bir count parametre alır. Bu işleyici, OData $skip sorgu parametresine düzgün bir şekilde çevrilir.

Birim testleri:

// OnSkip
Fact("Fold $skip 14 on Airlines",
    #table( type table [AirlineCode = text, Name = text] , {{"EK", "Emirates"}} ), 
    Table.Skip(Airlines, 14)
),
Fact("Fold $skip 0 and $top 1",
    #table( type table [AirlineCode = text, Name = text] , {{"AA", "American Airlines"}} ),
    Table.FirstN(Table.Skip(Airlines, 0), 1)
),

Uygulama:

// OnSkip - handles the Table.Skip transform.
// The count value should be >= 0.
OnSkip = (count as number) =>
    let
        newState = state & [ Skip = count ]
    in
        @View(newState),

ile eşleşen güncelleştirmeler CalculateUrl:

qsWithSkip = 
    if (state[Skip]? <> null) then
        qsWithTop & [ #"$skip" = Number.ToText(state[Skip]) ]
    else
        qsWithTop,

Daha fazla bilgi: Table.Skip

OnSelectColumns ile Table.SelectColumns İşleme

kullanıcı OnSelectColumns sonuç kümesindeki sütunları seçtiğinde veya kaldırdığında işleyici çağrılır. İşleyici, seçilecek bir veya daha fazla sütunu temsil eden bir listtext değer alır.

OData terimlerinde, bu işlem $select sorgu seçeneğiyle eşler.

Çok sayıda sütun içeren tablolarla uğraşırken, sütun seçiminin katlanması avantajı görünür hale gelir. $select işleci, sonuç kümesinden seçilmemiş sütunları kaldırır ve daha verimli sorgular elde eder.

Birim testleri:

// OnSelectColumns
Fact("Fold $select single column", 
    #table( type table [AirlineCode = text] , {{"AA"}} ),
    Table.FirstN(Table.SelectColumns(Airlines, {"AirlineCode"}), 1)
),
Fact("Fold $select multiple column", 
    #table( type table [UserName = text, FirstName = text, LastName = text],{{"russellwhyte", "Russell", "Whyte"}}), 
    Table.FirstN(Table.SelectColumns(People, {"UserName", "FirstName", "LastName"}), 1)
),
Fact("Fold $select with ignore column", 
    #table( type table [AirlineCode = text] , {{"AA"}} ),
    Table.FirstN(Table.SelectColumns(Airlines, {"AirlineCode", "DoesNotExist"}, MissingField.Ignore), 1)
),

İlk iki test Table.SelectColumns ile farklı sayıda sütun seçer ve test çalışmalarını basitleştirmek için bir Table.FirstN çağrısı içerir.

Not

Test yalnızca sütun adlarını döndürecekse (herhangi bir veri değil Table.ColumnNames kullanılarak), OData hizmetine yönelik istek hiçbir zaman gönderilmez. Bunun nedeni, çağrısının GetType M altyapısının sonucu hesaplamak için ihtiyaç duyduğu tüm bilgileri içeren şemayı döndürmesidir.

Üçüncü test, M altyapısına sonuç kümesinde mevcut olmayan seçili sütunları yoksaymalarını söyleyen MissingField.Ignore seçeneğini kullanır. İşleyicinin OnSelectColumns bu seçenek hakkında endişelenmesi gerekmez; M altyapısı bunu otomatik olarak işler (yani eksik sütunlar listeye dahil columns değildir).

Not

Table.SelectColumns için diğer seçenek olan MissingField.UseNull, işleyiciyi OnAddColumn uygulamak için bir bağlayıcı gerektirir. Bu, sonraki bir derste yapılacaktır.

için OnSelectColumns uygulaması iki şey yapar:

  • Seçili sütunların listesini öğesine stateekler.
  • Doğru tablo türünü ayarlayabilmeniz için değeri yeniden hesaplar Schema .
OnSelectColumns = (columns as list) =>
    let
        // get the current schema
        currentSchema = CalculateSchema(state),
        // get the columns from the current schema (which is an M Type value)
        rowRecordType = Type.RecordFields(Type.TableRow(currentSchema)),
        existingColumns = Record.FieldNames(rowRecordType),
        // calculate the new schema
        columnsToRemove = List.Difference(existingColumns, columns),
        updatedColumns = Record.RemoveFields(rowRecordType, columnsToRemove),
        newSchema = type table (Type.ForRecord(updatedColumns, false))
    in
        @View(state & 
            [ 
                SelectColumns = columns,
                Schema = newSchema
            ]
        ),

CalculateUrl durumundan sütunların listesini alacak ve bunları parametre için birleştirecek (bir ayırıcı ile) güncelleştirildi $select .

// Check for explicitly selected columns
qsWithSelect =
    if (state[SelectColumns]? <> null) then
        qsWithSkip & [ #"$select" = Text.Combine(state[SelectColumns], ",") ]
    else
        qsWithSkip,

OnSort ile Table.Sort İşleme

İşleyici OnSort , aşağıdaki türdeki kayıtların listesini alır:

type [ Name = text, Order = Int16.Type ]

Her kayıt, sütunun adını gösteren bir Name alan ve Order.Ascending veya Order.Descending değerine eşit bir Order alan içerir.

OData terimlerinde, bu işlem $orderby sorgu seçeneğiyle eşler. Söz $orderby diziminde, artan veya azalan sırayı göstermek için sütun adının ardından asc veya desc işareti bulunur. Birden çok sütuna göre sıraladığınızda, değerler virgülle ayrılır. columns Parametre birden fazla öğe içeriyorsa, bunların görüntülenme sırasını korumak önemlidir.

Birim testleri:

// OnSort
Fact("Fold $orderby single column",
    #table( type table [AirlineCode = text, Name = text], {{"TK", "Turkish Airlines"}}),
    Table.FirstN(Table.Sort(Airlines, {{"AirlineCode", Order.Descending}}), 1)
),
Fact("Fold $orderby multiple column",
    #table( type table [UserName = text], {{"javieralfred"}}),
    Table.SelectColumns(Table.FirstN(Table.Sort(People, {{"LastName", Order.Ascending}, {"UserName", Order.Descending}}), 1), {"UserName"})
)

Uygulama:

// OnSort - receives a list of records containing two fields: 
//    [Name]  - the name of the column to sort on
//    [Order] - equal to Order.Ascending or Order.Descending
// If there are multiple records, the sort order must be maintained.
//
// OData allows you to sort on columns that do not appear in the result
// set, so we do not have to validate that the sorted columns are in our 
// existing schema.
OnSort = (order as list) =>
    let
        // This will convert the list of records to a list of text,
        // where each entry is "<columnName> <asc|desc>"
        sorting = List.Transform(order, (o) => 
            let
                column = o[Name],
                order = o[Order],
                orderText = if (order = Order.Ascending) then "asc" else "desc"
            in
                column & " " & orderText
        ),
        orderBy = Text.Combine(sorting, ", ")
    in
        @View(state & [ OrderBy = orderBy ]),

Güncelleştirmeler:CalculateUrl

qsWithOrderBy = 
    if (state[OrderBy]? <> null) then
        qsWithSelect & [ #"$orderby" = state[OrderBy] ]
    else
        qsWithSelect,

GetRowCount ile Table.RowCount İşleme

İşleyici, GetRowCount uyguladığınız diğer sorgu işleyicilerinden farklı olarak, sonuç kümesinde beklenen satır sayısı olan tek bir değer döndürür. M sorgusunda bu değer genellikle Table.RowCount dönüşümünün sonucu olur.

Bu değeri bir OData sorgusunun parçası olarak işleme konusunda birkaç farklı seçeneğiniz vardır:

Sorgu parametresi yaklaşımının dezavantajı, sorgunun tamamını OData hizmetine göndermeniz gerektiğidir. Sayı sonuç kümesinin bir parçası olarak satır içi olarak geri geldiğinden, sonuç kümesindeki ilk veri sayfasını işlemeniz gerekir. Bu işlem yine de sonuç kümesinin tamamını okuyup satırları saymaktan daha verimli olsa da, muhtemelen yapmak istediğinizden daha fazla iştir.

Yol kesimi yaklaşımının avantajı, sonuçta yalnızca tek bir skaler değer almanızdır. Bu yaklaşım, tüm işlemi çok daha verimli hale getirir. Ancak, OData belirtiminde açıklandığı gibi, veya $skipgibi $top başka sorgu parametreleri eklerseniz /$count yol kesimi bir hata döndürür ve bu da yararlılığını sınırlar.

Bu öğreticide, yol kesimi yaklaşımını GetRowCount kullanarak işleyiciyi uyguladınız. Diğer sorgu parametreleri dahil edilirse alabileceğiniz hataları önlemek için, diğer durum değerlerini denetlemiş ve varsa "tanımlanamayan hata" (...) döndürmüştür. Table.View işleyicisinden herhangi bir hata döndürülmesi M altyapısına işlemin katlanmayacağını ve bunun yerine varsayılan işleyiciye geri dönmesi gerektiğini (bu durumda toplam satır sayısını saymak olabilir) bildirir.

İlk olarak bir birim testi ekleyin:

// GetRowCount
Fact("Fold $count", 15, Table.RowCount(Airlines)),

/$count Yol kesimi JSON sonuç kümesi yerine tek bir değer (düz/metin biçiminde) döndürdüğünden, isteği yapmak ve sonucu işlemek için yeni bir iç işlev (TripPin.Scalar) de eklemeniz gerekir.

// Similar to TripPin.Feed, but is expecting back a scalar value.
// This function returns the value from the service as plain text.
TripPin.Scalar = (url as text) as text =>
    let
        _url = Diagnostics.LogValue("TripPin.Scalar url", url),

        headers = DefaultRequestHeaders & [
            #"Accept" = "text/plain"
        ],

        response = Web.Contents(_url, [ Headers = headers ]),
        toText = Text.FromBinary(response)
    in
        toText;

Uygulama daha sonra bu işlevi kullanır (içinde başka sorgu parametresi bulunmazsa state):

GetRowCount = () as number =>
    if (Record.FieldCount(Record.RemoveFields(state, {"Url", "Entity", "Schema"}, MissingField.Ignore)) > 0) then
        ...
    else
        let
            newState = state & [ RowCountOnly = true ],
            finalUrl = CalculateUrl(newState),
            value = TripPin.Scalar(finalUrl),
            converted = Number.FromText(value)
        in
            converted,

alanı CalculateUrl içinde ayarlanmışsa RowCountOnly işlev URL'ye stateeklenecek /$count şekilde güncelleştirilir.

// Check for $count. If all we want is a row count,
// then we add /$count to the path value (following the entity name).
urlWithRowCount =
    if (state[RowCountOnly]? = true) then
        urlWithEntity & "/$count"
    else
        urlWithEntity,

Yeni Table.RowCount birim testi artık geçmelidir.

Geri dönüş durumunu test etmek için hatayı zorlayan başka bir test eklersiniz.

İlk olarak, bir işlemin sonucunu katlama hatası için denetleen bir try yardımcı yöntemi ekleyin.

// Returns true if there is a folding error, or the original record (for logging purposes) if not.
Test.IsFoldingError = (tryResult as record) =>
    if ( tryResult[HasError]? = true and tryResult[Error][Message] = "We couldn't fold the expression to the data source. Please try a simpler expression.") then
        true
    else
        tryResult;

Ardından hatayı zorlamak için hem Table.RowCount hem de Table.FirstN kullanan bir test ekleyin.

// test will fail if "Fail on Folding Error" is set to false
Fact("Fold $count + $top *error*", true, Test.IsFoldingError(try Table.RowCount(Table.FirstN(Airlines, 3)))),

Burada önemli bir not, işlem yerel (varsayılan) işleyiciye geri döndüğünden, Katlama Hatasında Hata değeri olarak ayarlandığında falsebu testin Table.RowCount bir hata döndürdüğüdür. Testlerin Katlanırken Hata ile çalıştırılması hatanıntrue başarısız olmasına neden olur Table.RowCount ve testin başarılı olmasına izin verir.

Sonuç

Bağlayıcınız için Table.View'un uygulanması, kodunuz için önemli miktarda karmaşıklık ekler. M altyapısı tüm dönüştürmeleri yerel olarak işleyebildiğinden Table.View işleyicileri eklemek kullanıcılarınız için yeni senaryoları etkinleştirmez, ancak daha verimli işlemeye (ve potansiyel olarak daha mutlu kullanıcılara) neden olur. Table.View işleyicilerinin isteğe bağlı olmasının temel avantajlarından biri, bağlayıcınızın geriye dönük uyumluluğunu etkilemeden artımlı olarak yeni işlevler eklemenize olanak sağlamasıdır.

Çoğu bağlayıcı için, döndürülen satır sayısını sınırladığı için $top uygulanması gereken önemli (ve temel) bir işleyicidir OnTake (OData'da olarak çevrilir). Power Query deneyimi, gezginde ve sorgu düzenleyicisinde önizlemeleri görüntülerken her zaman bir OnTake1000 satır gerçekleştirir, böylece kullanıcılarınız daha büyük veri kümeleriyle çalışırken önemli performans geliştirmeleri görebilir.