TripPin — część 10 — składanie zapytań podstawowych
Uwaga
Ta zawartość obecnie odwołuje się do zawartości ze starszej implementacji dzienników w programie Visual Studio. Zawartość zostanie zaktualizowana w najbliższej przyszłości, aby uwzględnić nowy zestaw POWER Query SDK w programie Visual Studio Code.
Ten wieloczęściowy samouczek obejmuje tworzenie nowego rozszerzenia źródła danych dla dodatku Power Query. Samouczek ma być wykonywany sekwencyjnie — każda lekcja opiera się na łączniku utworzonym w poprzednich lekcjach, przyrostowo dodając nowe możliwości do łącznika.
W tej lekcji wykonasz następujące lekcji:
- Poznaj podstawy składania zapytań
- Dowiedz się więcej o funkcji Table.View
- Replikowanie programów obsługi składania zapytań OData dla:
$top
$skip
$count
$select
$orderby
Jedną z zaawansowanych funkcji języka M jest możliwość wypychania transformacji do co najmniej jednego bazowego źródła danych. Ta funkcja jest nazywana składaniem zapytań (inne narzędzia/technologie odnoszą się również do podobnej funkcji jak Wypychanie predykatu lub Delegowanie zapytań).
Podczas tworzenia łącznika niestandardowego korzystającego z funkcji M z wbudowanymi funkcjami składania zapytań, takimi jak OData.Feed lub Odbc.DataSource, łącznik automatycznie dziedziczy tę funkcję bezpłatnie.
Ten samouczek replikuje wbudowane zachowanie składania zapytań dla usługi OData przez zaimplementowanie procedur obsługi funkcji dla funkcji Table.View . Ta część samouczka implementuje niektóre z łatwiejszych procedur obsługi (czyli tych, które nie wymagają analizowania wyrażeń i śledzenia stanu).
Aby dowiedzieć się więcej o możliwościach zapytań oferowanych przez usługę OData, przejdź do sekcji OData v4 URL Conventions (Konwencje adresów URL OData w wersji 4).
Uwaga
Jak wspomniano wcześniej, funkcja OData.Feed automatycznie zapewnia możliwości składania zapytań. Ponieważ seria TripPin traktuje usługę OData jako zwykły interfejs API REST, używając biblioteki Web.Contents , a nie OData.Feed, musisz samodzielnie zaimplementować procedury obsługi składania zapytań. W przypadku rzeczywistego użycia zalecamy używanie protokołu OData.Feed zawsze, gdy jest to możliwe.
Przejdź do sekcji Przegląd oceny zapytań i składania zapytań w dodatku Power Query , aby uzyskać więcej informacji na temat składania zapytań.
Korzystanie z tabeli.View
Funkcja Table.View umożliwia łącznikowi niestandardowemu zastępowanie domyślnych procedur obsługi przekształceń dla źródła danych. Implementacja obiektu Table.View zapewni funkcję dla co najmniej jednego obsługiwanego programu obsługi. Jeśli program obsługi jest nieimplementowany lub zwraca error
podczas oceny, aparat M powraca do domyślnej procedury obsługi.
Gdy łącznik niestandardowy używa funkcji, która nie obsługuje składania niejawnych zapytań, takich jak Web.Contents, domyślne procedury obsługi przekształceń są zawsze wykonywane lokalnie. Jeśli interfejs API REST, z którym nawiązujesz połączenie, obsługuje parametry zapytania w ramach zapytania, funkcja Table.View umożliwia dodawanie optymalizacji, które umożliwiają wypchnięcie transformacji do usługi.
Funkcja Table.View ma następujący podpis:
Table.View(table as nullable table, handlers as record) as table
Implementacja opakowuje główną funkcję źródła danych. Istnieją dwa wymagane programy obsługi dla tabeli.View:
GetType
— zwraca oczekiwanytable type
wynik zapytaniaGetRows
— zwraca rzeczywistytable
wynik funkcji źródła danych
Najprostsza implementacja będzie podobna do poniższego przykładu:
TripPin.SuperSimpleView = (url as text, entity as text) as table =>
Table.View(null, [
GetType = () => Value.Type(GetRows()),
GetRows = () => GetEntity(url, entity)
]);
Zaktualizuj funkcję tak, aby wywołała TripPin.SuperSimpleView
metodę TripPinNavTable
zamiast GetEntity
:
withData = Table.AddColumn(rename, "Data", each TripPin.SuperSimpleView(url, [Name]), type table),
Jeśli ponownie uruchomisz testy jednostkowe, zobaczysz, że zachowanie funkcji nie zostanie zmienione. W takim przypadku implementacja Table.View jest po prostu przekazywana przez wywołanie metody .GetEntity
Ponieważ nie zaimplementowano jeszcze żadnych procedur obsługi transformacji, oryginalny url
parametr pozostaje nietknięty.
Początkowa implementacja tabeli.View
Powyższa implementacja tabeli.View jest prosta, ale nie jest bardzo przydatna. Poniższa implementacja jest używana jako punkt odniesienia — nie implementuje żadnych funkcji składania, ale ma szkielet, który należy wykonać.
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]);
Jeśli przyjrzysz się wywołaniu funkcji Table.View, zobaczysz dodatkową funkcję otoki wokół rekordu handlers
—Diagnostics.WrapHandlers
. Ta funkcja pomocnika znajduje się w module Diagnostyka (wprowadzonym w lekcji dodawania diagnostyki ) i zapewnia przydatny sposób automatycznego śledzenia błędów zgłaszanych przez poszczególne procedury obsługi.
Funkcje GetType
i GetRows
są aktualizowane w celu korzystania z dwóch nowych funkcji pomocnika —CalculateSchema
i CalculateUrl
. W tej chwili implementacje tych funkcji są dość proste — zauważ, że zawierają one części tego, co zostało wcześniej wykonane przez GetEntity
funkcję.
Na koniec zwróć uwagę, że definiujesz funkcję wewnętrzną state
(View
), która akceptuje parametr.
W miarę implementowania większej liczby procedur obsługi będą one rekursywnie wywoływać funkcję wewnętrzną View
, aktualizując i przekazując je state
w miarę ich przechodzenia.
TripPinNavTable
Ponownie zaktualizuj funkcję, zastępując wywołanie TripPin.SuperSimpleView
metody wywołaniem nowej TripPin.View
funkcji i ponownie uruchom testy jednostkowe. Nie zobaczysz jeszcze żadnych nowych funkcji, ale masz teraz solidny punkt odniesienia do testowania.
Implementowanie składania zapytań
Ponieważ aparat języka M automatycznie wraca do przetwarzania lokalnego, gdy nie można złożyć zapytania, należy wykonać kilka dodatkowych kroków, aby sprawdzić, czy programy obsługi Table.View działają poprawnie.
Ręcznym sposobem sprawdzania poprawności zachowania składania jest obserwowanie żądań adresów URL wykonywanych przez testy jednostkowe za pomocą narzędzia takiego jak Fiddler. Alternatywnie dodane TripPin.Feed
rejestrowanie diagnostyczne emituje uruchamiany pełny adres URL, który powinien zawierać parametry ciągu zapytania OData dodane przez programy obsługi.
Zautomatyzowanym sposobem sprawdzania poprawności składania zapytań jest wymusić niepowodzenie wykonywania testu jednostkowego, jeśli zapytanie nie zostanie w pełni złożone. Można to zrobić, otwierając właściwości projektu i ustawiając wartość Błąd podczas składania błędu na true. Po włączeniu tego ustawienia każde zapytanie wymagające lokalnego przetwarzania powoduje następujący błąd:
Nie można złożyć wyrażenia do źródła. Spróbuj użyć prostszego wyrażenia.
Możesz to przetestować, dodając nowy Fact
plik testu jednostkowego zawierający co najmniej jedną transformację tabeli.
// Query folding tests
Fact("Fold $top 1 on Airlines",
#table( type table [AirlineCode = text, Name = text] , {{"AA", "American Airlines"}} ),
Table.FirstN(Airlines, 1)
)
Uwaga
Ustawienie Błąd w przypadku niepowodzenia składania jest podejściem "wszystko lub nic". Jeśli chcesz przetestować zapytania, które nie są przeznaczone do składania w ramach testów jednostkowych, należy dodać pewną logikę warunkową, aby odpowiednio włączyć/wyłączyć testy.
Pozostałe sekcje tego samouczka dodają nową procedurę obsługi Table.View . Wykonujesz podejście do programowania opartego na testach (TDD ), w którym najpierw dodasz testy jednostkowe zakończone niepowodzeniem, a następnie zaimplementujesz kod języka M, aby je rozwiązać.
W poniższych sekcjach obsługi opisano funkcje zapewniane przez program obsługi, równoważną składnię zapytań OData, testy jednostkowe i implementację. Korzystając z opisanego wcześniej kodu tworzenia szkieletów, każda implementacja programu obsługi wymaga dwóch zmian:
- Dodanie programu obsługi do obiektu Table.View , który aktualizuje
state
rekord. - Modyfikowanie
CalculateUrl
w celu pobrania wartości z elementustate
i dodania do parametrów adresu URL i/lub ciągu zapytania.
Obsługa biblioteki Table.FirstN za pomocą funkcji OnTake
Procedura OnTake
obsługi odbiera parametr , który jest maksymalną count
liczbą wierszy do pobrania z GetRows
.
W kategoriach OData można to przetłumaczyć na parametr zapytania $top .
Należy użyć następujących testów jednostkowych:
// 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)
),
Te testy używają metody Table.FirstN do filtrowania do zestawu wyników na pierwszą liczbę wierszy X. Jeśli uruchomisz te testy z ustawieniem False
Błąd podczas składania błędu (wartość domyślna), testy powinny zakończyć się powodzeniem, ale jeśli uruchomisz program Fiddler (lub sprawdź dzienniki śledzenia), zwróć uwagę, że wysłane żądanie nie zawiera żadnych parametrów zapytania OData.
Jeśli ustawisz wartość Błąd podczas składania błędu True
, testy kończą się niepowodzeniem z powodu błędu Please try a simpler expression.
. Aby naprawić ten błąd, należy zdefiniować pierwszą procedurę obsługi Table.View dla elementu OnTake
.
Procedura OnTake
obsługi wygląda podobnie do następującego kodu:
OnTake = (count as number) =>
let
// Add a record with Top defined to our state
newState = state & [ Top = count ]
in
@View(newState),
Funkcja CalculateUrl
jest aktualizowana w celu wyodrębnienia Top
wartości z rekordu state
i ustawienia odpowiedniego parametru w ciągu zapytania.
// 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
Ponowne uruchomienie testów jednostkowych oznacza, że adres URL, do którego uzyskujesz dostęp, zawiera $top
teraz parametr . Ze względu na kodowanie adresów URL jest wyświetlany jako %24top
, ale usługa OData jest wystarczająco inteligentna, $top
aby ją automatycznie przekonwertować.
Obsługa funkcji Table.Skip przy użyciu narzędzia OnSkip
Procedura obsługi jest bardzo podobna OnSkip
do OnTake
. Otrzymuje count
parametr, który jest liczbą wierszy do pominięcia z zestawu wyników. Ta procedura obsługi ładnie tłumaczy się na parametr zapytania OData $skip .
Testy jednostkowe:
// 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)
),
Implementacja:
// OnSkip - handles the Table.Skip transform.
// The count value should be >= 0.
OnSkip = (count as number) =>
let
newState = state & [ Skip = count ]
in
@View(newState),
Dopasowywanie aktualizacji do elementu CalculateUrl
:
qsWithSkip =
if (state[Skip]? <> null) then
qsWithTop & [ #"$skip" = Number.ToText(state[Skip]) ]
else
qsWithTop,
Więcej informacji: Table.Skip
Obsługa funkcji Table.SelectColumns za pomocą funkcji OnSelectColumns
Procedura OnSelectColumns
obsługi jest wywoływana, gdy użytkownik wybiera lub usuwa kolumny z zestawu wyników. Procedura obsługi odbiera list
text
wartości reprezentujące co najmniej jedną kolumnę do wybrania.
W kategoriach OData ta operacja mapuje na opcję zapytania $select .
Zaleta składania wyboru kolumn staje się widoczna, gdy masz do czynienia z tabelami z wieloma kolumnami. Operator $select
usuwa niezaznaczone kolumny z zestawu wyników, co skutkuje bardziej wydajnymi zapytaniami.
Testy jednostkowe:
// 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)
),
Pierwsze dwa testy wybierają różne liczby kolumn z kolumnami Table.SelectColumns i zawierają wywołanie Table.FirstN , aby uprościć przypadek testowy.
Uwaga
Jeśli test miał po prostu zwrócić nazwy kolumn (przy użyciu table.ColumnNames, a nie żadnych danych, żądanie do usługi OData nigdy nie zostanie wysłane. Dzieje się tak, ponieważ wywołanie GetType
metody zwróci schemat zawierający wszystkie informacje, które aparat M musi obliczyć wynik.
Trzeci test używa opcji MissingField.Ignore , która nakazuje aparatowi M ignorowanie wszystkich wybranych kolumn, które nie istnieją w zestawie wyników. Program OnSelectColumns
obsługi nie musi się martwić o tę opcję — aparat M obsługuje ją automatycznie (czyli brak kolumn nie znajduje się na columns
liście).
Uwaga
Druga opcja dla table.SelectColumns, MissingField.UseNull, wymaga łącznika do zaimplementowania OnAddColumn
programu obsługi. Zostanie to zrobione w kolejnej lekcji.
Implementacja obejmuje OnSelectColumns
dwie rzeczy:
- Dodaje listę wybranych kolumn do elementu
state
. - Ponownie oblicza
Schema
wartość, aby można było ustawić odpowiedni typ tabeli.
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
Program jest aktualizowany w celu pobrania listy kolumn ze stanu i połączenia ich (z separatorem) dla parametru $select
.
// Check for explicitly selected columns
qsWithSelect =
if (state[SelectColumns]? <> null) then
qsWithSkip & [ #"$select" = Text.Combine(state[SelectColumns], ",") ]
else
qsWithSkip,
Obsługa obiektu Table.Sort przy użyciu programu OnSort
Procedura OnSort
obsługi otrzymuje listę rekordów typu:
type [ Name = text, Order = Int16.Type ]
Każdy rekord zawiera Name
pole, wskazujące nazwę kolumny i Order
pole, które jest równe Order.Ascending lub Order.Descending.
W kategoriach OData ta operacja mapuje na opcję zapytania $orderby .
Składnia $orderby
ma nazwę kolumny, po której następuje asc
lub desc
wskazująca kolejność rosnącą lub malejącą. Podczas sortowania na wielu kolumnach wartości są rozdzielane przecinkami. columns
Jeśli parametr zawiera więcej niż jeden element, ważne jest zachowanie kolejności ich wyświetlania.
Testy jednostkowe:
// 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"})
)
Implementacja:
// 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 ]),
Aktualizacje do :CalculateUrl
qsWithOrderBy =
if (state[OrderBy]? <> null) then
qsWithSelect & [ #"$orderby" = state[OrderBy] ]
else
qsWithSelect,
Obsługa obiektu Table.RowCount za pomocą polecenia GetRowCount
W przeciwieństwie do innych procedur obsługi zapytań, które implementujesz, GetRowCount
procedura obsługi zwraca pojedynczą wartość — liczbę wierszy oczekiwanych w zestawie wyników. W zapytaniu języka M ta wartość zazwyczaj będzie wynikiem przekształcenia Table.RowCount .
Istnieje kilka różnych opcji obsługi tej wartości w ramach zapytania OData:
- Parametr zapytania $count, który zwraca liczbę jako osobne pole w zestawie wyników.
- /$count segment ścieżki, który zwraca tylko całkowitą liczbę jako wartość skalarną.
Wadą podejścia do parametru zapytania jest to, że nadal trzeba wysłać całe zapytanie do usługi OData. Ponieważ liczba jest w tekście w ramach zestawu wyników, musisz przetworzyć pierwszą stronę danych z zestawu wyników. Chociaż ten proces jest nadal bardziej wydajny niż odczytywanie całego zestawu wyników i liczenie wierszy, prawdopodobnie jest to jeszcze więcej pracy niż chcesz wykonać.
Zaletą podejścia segmentu ścieżki jest to, że w wyniku otrzymujesz tylko jedną wartość skalarną. Takie podejście sprawia, że cała operacja jest o wiele wydajniejsza. Jednak zgodnie ze specyfikacją OData /$count segment ścieżki zwraca błąd, jeśli uwzględnisz inne parametry zapytania, takie jak $top
lub $skip
, co ogranicza jego użyteczność.
W tym samouczku zaimplementowano procedurę GetRowCount
obsługi przy użyciu podejścia segmentu ścieżki. Aby uniknąć błędów, które można uzyskać, jeśli zostały uwzględnione inne parametry zapytania, sprawdzono inne wartości stanu i zwróciło komunikat "nieimplementowany błąd" () w...
przypadku znalezienia dowolnego. Zwracanie dowolnego błędu z programu obsługi Table.View informuje aparat M, że nie można złożyć operacji i powinien powrócić do domyślnej procedury obsługi (co w tym przypadku zlicza łączną liczbę wierszy).
Najpierw dodaj test jednostkowy:
// GetRowCount
Fact("Fold $count", 15, Table.RowCount(Airlines)),
/$count
Ponieważ segment ścieżki zwraca pojedynczą wartość (w formacie zwykłego/tekstowego) zamiast zestawu wyników JSON, musisz również dodać nową funkcję wewnętrzną (TripPin.Scalar
) do tworzenia żądania i obsługi wyniku.
// 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;
Implementacja następnie używa tej funkcji (jeśli nie znaleziono żadnych innych parametrów zapytania w obiekcie 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,
Funkcja zostanie zaktualizowana CalculateUrl
w celu dołączenia /$count
do adresu URL, jeśli RowCountOnly
pole jest ustawione w elemecie state
.
// 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,
Nowy Table.RowCount
test jednostkowy powinien teraz przejść.
Aby przetestować przypadek rezerwowy, należy dodać kolejny test, który wymusza błąd.
Najpierw dodaj metodę pomocnika, która sprawdza wynik try
operacji pod kątem błędu składania.
// 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;
Następnie dodaj test, który używa obu tabel Table.RowCount i Table.FirstN , aby wymusić błąd.
// 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)))),
Należy pamiętać, że ten test zwraca teraz błąd, jeśli dla błędu składania ustawiono false
wartość , ponieważ Table.RowCount
operacja powraca do lokalnej (domyślnej) procedury obsługi. Uruchamianie testów z błędem przy składaniu błędu ustawiono przyczynę true
Table.RowCount
niepowodzenia i umożliwia pomyślne przeprowadzenie testu.
Podsumowanie
Implementowanie elementu Table.View dla łącznika zwiększa złożoność kodu. Ponieważ aparat języka M może przetwarzać wszystkie przekształcenia lokalnie, dodanie programów obsługi Table.View nie włącza nowych scenariuszy dla użytkowników, ale skutkuje bardziej wydajnym przetwarzaniem (i potencjalnie szczęśliwszymi użytkownikami). Jedną z głównych zalet obsługi Table.View jest opcjonalna jest możliwość przyrostowego dodawania nowych funkcji bez wpływu na zgodność z poprzednimi wersjami łącznika.
W przypadku większości łączników ważna (i podstawowa) procedura obsługi do zaimplementowania to OnTake
(co przekłada się na $top
wartość OData), ponieważ ogranicza liczbę zwracanych wierszy. Środowisko dodatku Power Query zawsze wykonuje wiersze OnTake
1000
podczas wyświetlania podglądów w nawigatorze i edytorze zapytań, dzięki czemu użytkownicy mogą zobaczyć znaczne ulepszenia wydajności podczas pracy z większymi zestawami danych.