TripPin 10. rész – Egyszerű lekérdezés-összecsukás
Feljegyzés
Ez a tartalom jelenleg egy örökölt implementációból származó tartalmakra hivatkozik a Visual Studióban lévő naplókhoz. A tartalom a közeljövőben frissülni fog, hogy lefedje a Visual Studio Code új Power Query SDK-ját.
Ez a többrészes oktatóanyag a Power Query új adatforrásbővítményének létrehozását ismerteti. Az oktatóanyagot egymás után kell elvégezni – minden lecke az előző leckékben létrehozott összekötőre épül, és növekményesen új képességeket ad hozzá az összekötőhöz.
Ebben a leckében a következőt fogja:
- A lekérdezések összecsukásának alapjai
- További információ a Table.View függvényről
- OData-lekérdezés összecsukható kezelőinek replikálása a következőhöz:
$top
$skip
$count
$select
$orderby
Az M nyelv egyik hatékony funkciója, hogy képes leküldni az átalakítást egy vagy több mögöttes adatforrásba. Ezt a képességet lekérdezés-összecsukásnak nevezzük (más eszközök/technológiák is hasonló függvényre hivatkoznak, mint a Predicate Pushdown vagy a Query Delegálás).
Ha olyan egyéni összekötőt hoz létre, amely beépített lekérdezés-összecsukási képességekkel (például OData.Feed vagy Odbc.DataSource) rendelkező M függvényt használ, az összekötő automatikusan ingyenesen örökli ezt a képességet.
Ez az oktatóanyag replikálja az OData beépített lekérdezés-összecsukási viselkedését a Table.View függvény függvénykezelőinek implementálásával. Az oktatóanyag ezen része implementálja a könnyebben implementálható kezelők némelyikét (vagyis azokat, amelyek nem igényelnek kifejezés-elemzést és állapotkövetést).
Az OData-szolgáltatás által kínált lekérdezési képességekről az OData v4 URL-konvenciók című témakörben olvashat bővebben.
Feljegyzés
Ahogy korábban említettem, az OData.Feed függvény automatikusan biztosít lekérdezés-összecsukási képességeket. Mivel a TripPin-sorozat az OData szolgáltatást normál REST API-ként kezeli, az OData.Feed helyett a Web.Contents szolgáltatást használja, saját maga kell implementálnia a lekérdezés-összecsukható kezelőket. Valós használat esetén javasoljuk, hogy az OData.Feedet használja, amikor csak lehetséges.
A lekérdezések összecsukásával kapcsolatos további információkért tekintse meg a lekérdezések kiértékelésének és a lekérdezések összecsukásának áttekintését a Power Queryben .
A Table.View használata
A Table.View függvény lehetővé teszi, hogy egy egyéni összekötő felülírja az adatforrás alapértelmezett átalakítási kezelőinek értékét. A Table.View implementációja egy vagy több támogatott kezelőhöz biztosít függvényt. Ha egy kezelő nem működik, vagy a kiértékelés során ad vissza egy error
hibát, az M motor visszaáll az alapértelmezett kezelőre.
Ha egy egyéni összekötő olyan függvényt használ, amely nem támogatja az implicit lekérdezések összecsukását(például Web.Contents), az alapértelmezett átalakítási kezelők mindig helyben lesznek végrehajtva. Ha a lekérdezés részeként a lekérdezés részeként a lekérdezési paramétereket támogató REST API-hoz csatlakozik, a Table.View lehetővé teszi olyan optimalizálások hozzáadását, amelyek lehetővé teszik az átalakítási munka leküldését a szolgáltatásba.
A Table.View függvény a következő aláírással rendelkezik:
Table.View(table as nullable table, handlers as record) as table
Az implementáció körbefuttatja a fő adatforrásfüggvényt. A Table.View két szükséges kezelőt tartalmaz:
GetType
— a lekérdezés eredményének várttable type
értékét adja visszaGetRows
— az adatforrásfüggvény ténylegestable
eredményét adja vissza
A legegyszerűbb implementáció a következő példához hasonló:
TripPin.SuperSimpleView = (url as text, entity as text) as table =>
Table.View(null, [
GetType = () => Value.Type(GetRows()),
GetRows = () => GetEntity(url, entity)
]);
Frissítse a függvényt TripPinNavTable
a következő helyett hívásra TripPin.SuperSimpleView
GetEntity
:
withData = Table.AddColumn(rename, "Data", each TripPin.SuperSimpleView(url, [Name]), type table),
Ha újrafuttatja az egységteszteket, láthatja, hogy a függvény működése nem változik. Ebben az esetben a Table.View implementáció egyszerűen áthalad a híváson GetEntity
. Mivel még nem implementált átalakítási kezelőket (még), az eredeti url
paraméter érintetlen marad.
A Table.View kezdeti implementálása
A Table.View fenti implementációja egyszerű, de nem túl hasznos. A következő implementációt használja alapkonfigurációként – nem implementál összecsukható funkciókat, de rendelkezik a szükséges állványzatkal.
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]);
Ha megtekinti a Table.View hívását, egy további burkolófüggvény jelenik meg a handlers
rekord körül –Diagnostics.WrapHandlers
Ez a segédfüggvény a Diagnosztika modulban található (amely a diagnosztikai leckében lett bevezetve), és hasznos módot kínál az egyes kezelők által felmerülő hibák automatikus nyomon követésére.
Az GetType
és GetRows
a függvények frissülnek, hogy két új segédfüggvényt használjon–CalculateSchema
és CalculateUrl
. Jelenleg ezeknek a függvényeknek a implementációi meglehetősen egyszerűek – figyelje meg, hogy azok a függvény által GetEntity
korábban elvégzett műveletek részeit tartalmazzák.
Végül figyelje meg, hogy egy olyan belső függvényt (View
) definiál, amely elfogadja a paramétert state
.
A további kezelők implementálása során rekurzív módon meghívják a belső View
függvényt, és folyamatosan frissülnek és haladnak state
tovább.
Frissítse ismét a TripPinNavTable
függvényt, cserélje le a hívást TripPin.SuperSimpleView
az új TripPin.View
függvény hívására, és futtassa újra az egységteszteket. Egyelőre nem fog új funkciókat látni, de most már rendelkezik egy szilárd alapkonfigurációval a teszteléshez.
Lekérdezés-összecsukás implementálása
Mivel az M motor automatikusan visszaesik a helyi feldolgozásra, amikor egy lekérdezés nem hajtható végre, további lépéseket kell tennie annak ellenőrzéséhez, hogy a Table.View kezelői megfelelően működnek-e.
Az összecsukható viselkedés ellenőrzésének manuális módja, ha az egységtesztek által a Fiddlerhez hasonló eszközzel végzett URL-kéréseket figyeli. Alternatív megoldásként a diagnosztikai naplózás, amelyet a TripPin.Feed
teljes futtatandó URL-cím kibocsát, amelynek tartalmaznia kell a kezelők által hozzáadott OData lekérdezési sztringparamétereket.
A lekérdezés-összecsukás ellenőrzésének automatikus módja, ha az egységteszt végrehajtását sikertelenre kényszeríti, ha egy lekérdezés nem hajtja végre teljesen. Ezt úgy teheti meg, hogy megnyitja a projekt tulajdonságait, és igaz értékre állítja a sikertelen összecsukási hibát. Ha ez a beállítás engedélyezve van, a helyi feldolgozást igénylő lekérdezések a következő hibát eredményezik:
A kifejezést nem sikerült a forrásra hajtani. Próbálkozzon egyszerűbb kifejezéssel.
Ezt úgy tesztelheti, hogy hozzáad egy újat Fact
az egységtesztfájlhoz, amely egy vagy több táblaátalakítást tartalmaz.
// Query folding tests
Fact("Fold $top 1 on Airlines",
#table( type table [AirlineCode = text, Name = text] , {{"AA", "American Airlines"}} ),
Table.FirstN(Airlines, 1)
)
Feljegyzés
Az Összecsukási hiba beállítás "minden vagy semmi" megközelítés. Ha olyan lekérdezéseket szeretne tesztelni, amelyek nem az egységtesztek részeként való összecsukásra vannak tervezve, a tesztek megfelelő engedélyezéséhez/letiltásához fel kell vennie néhány feltételes logikát.
Az oktatóanyag fennmaradó szakaszai mindegyike új Table.View kezelőt ad hozzá. Egy tesztalapú fejlesztési (TDD) megközelítést használ, amelyben először sikertelen egységteszteket ad hozzá, majd implementálja az M-kódot a feloldásukhoz.
Az alábbi kezelőszakaszok a kezelő által biztosított funkciókat, az OData egyenértékű lekérdezési szintaxist, az egységteszteket és az implementációt ismertetik. A korábban ismertetett állványzatkód használatával minden kezelő implementációja két módosítást igényel:
- A rekordot frissítő kezelő hozzáadása a
state
Table.View nézethez. CalculateUrl
Módosítás az értékek lekéréséhez ésstate
az URL-címhez és/vagy a lekérdezési sztring paramétereihez való hozzáadáshoz.
Table.FirstN kezelése az OnTake-nal
A OnTake
kezelő egy paramétert count
kap, amely az átveendő GetRows
sorok maximális száma.
OData-kifejezésekben ezt lefordíthatja a $top lekérdezési paraméterre.
A következő egységteszteket használja:
// 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)
),
Ezek a tesztek a Table.FirstN használatával szűrnek az eredményhalmazra az első X számú sorra. Ha az összecsukási hiba hiba beállításával False
futtatja ezeket a teszteket (alapértelmezés szerint), a teszteknek sikeresnek kell lennie, de ha a Fiddlert futtatja (vagy ellenőrzi a nyomkövetési naplókat), figyelje meg, hogy az elküldött kérés nem tartalmaz OData-lekérdezési paramétereket.
Ha az összecsukási hiba hibátTrue
állítja be, a tesztek a hibával Please try a simpler expression.
meghiúsulnak. A hiba elhárításához meg kell adnia az első Table.View kezelőt a következőhöz OnTake
: .
A OnTake
kezelő a következő kódhoz hasonlóan néz ki:
OnTake = (count as number) =>
let
// Add a record with Top defined to our state
newState = state & [ Top = count ]
in
@View(newState),
A CalculateUrl
függvény frissül, hogy kinyerje az Top
értéket a state
rekordból, és állítsa be a megfelelő paramétert a lekérdezési sztringben.
// 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
Az egységtesztek újrafuttatásakor figyelje meg, hogy az ön által elért URL-cím tartalmazza a paramétert $top
. Az URL-kódolás miatt úgy jelenik meg, $top
mint %24top
, de az OData szolgáltatás elég intelligens ahhoz, hogy automatikusan konvertálja.
A Table.Skip kezelése az OnSkip használatával
A OnSkip
kezelő nagyon hasonlít OnTake
. Egy paramétert count
kap, amely az eredményhalmazból kihagyandó sorok száma. Ez a kezelő szépen lefordítja az OData $skip lekérdezési paramétert.
Egységtesztek:
// 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)
),
Implementálás:
// OnSkip - handles the Table.Skip transform.
// The count value should be >= 0.
OnSkip = (count as number) =>
let
newState = state & [ Skip = count ]
in
@View(newState),
A következőhöz tartozó frissítések egyeztetése CalculateUrl
:
qsWithSkip =
if (state[Skip]? <> null) then
qsWithTop & [ #"$skip" = Number.ToText(state[Skip]) ]
else
qsWithTop,
További információ: Table.Skip
Table.SelectColumns kezelése OnSelectColumns használatával
A OnSelectColumns
kezelő akkor lesz meghívva, ha a felhasználó kiválasztja vagy eltávolítja az oszlopokat az eredményhalmazból. A kezelő egy értéket kap list
text
, amely egy vagy több kijelölendő oszlopot jelöl.
OData-kifejezésekben ez a művelet a $select lekérdezési beállításhoz lesz leképezve.
Az oszlopok összecsukásának előnye akkor válik nyilvánvalóvá, ha sok oszlopot tartalmazó táblákkal foglalkozik. Az $select
operátor eltávolítja a nem kijelölt oszlopokat az eredményhalmazból, ami hatékonyabb lekérdezéseket eredményez.
Egységtesztek:
// 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)
),
Az első két teszt különböző számú oszlopot jelöl ki a Table.SelectColumns használatával, és egy Table.FirstN-hívást is tartalmaz a teszteset egyszerűsítése érdekében.
Feljegyzés
Ha a teszt csak az oszlopneveket adja vissza (a Table.ColumnNames használatával, nem pedig adatokkal, akkor a rendszer soha nem küldi el a kérelmet az OData szolgáltatásnak. Ennek az az oka, hogy GetType
a hívás visszaadja a sémát, amely tartalmazza az M motor által az eredmény kiszámításához szükséges összes információt.
A harmadik teszt a MissingField.Ignore lehetőséget használja, amely arra utasítja az M motort, hogy hagyja figyelmen kívül az eredményhalmazban nem létező kijelölt oszlopokat. A OnSelectColumns
kezelőnek nem kell aggódnia ezzel a beállítással – az M motor automatikusan kezeli (vagyis a hiányzó oszlopok nem szerepelnek a columns
listában).
Feljegyzés
A Table.SelectColumns(MissingField.UseNull) másik lehetőségéhez egy összekötőre van szükség a OnAddColumn
kezelő implementálásához. Ezt egy későbbi leckében fogjuk elvégezni.
A megvalósítás OnSelectColumns
két dolgot tesz:
- Hozzáadja a kijelölt oszlopok listáját a
state
. - Újraszámítja az
Schema
értéket, hogy meg tudja állítani a megfelelő táblázattípust.
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
frissül, hogy lekérje az oszlopok listáját az állapotból, és egyesítse őket (elválasztójellel) a $select
paraméterhez.
// Check for explicitly selected columns
qsWithSelect =
if (state[SelectColumns]? <> null) then
qsWithSkip & [ #"$select" = Text.Combine(state[SelectColumns], ",") ]
else
qsWithSkip,
Table.Sort kezelése az OnSorttal
A OnSort
kezelő megkapja a következő típusú rekordok listáját:
type [ Name = text, Order = Int16.Type ]
Minden rekord tartalmaz egy Name
mezőt, amely az oszlop nevét jelzi, és egy Order
olyan mezőt, amely egyenlő az Order.Ascending vagy a Order.Descending mezővel.
OData-kifejezésekben ez a művelet a $orderby lekérdezési beállításhoz lesz leképezve.
A $orderby
szintaxis az oszlop nevét követi asc
, illetve desc
növekvő vagy csökkenő sorrendet jelöl. Ha több oszlopra rendez, az értékek vesszővel vannak elválasztva. Ha a columns
paraméter egynél több elemet tartalmaz, fontos fenntartani a megjelenítési sorrendet.
Egységtesztek:
// 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"})
)
Implementálás:
// 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 ]),
Frissítések:CalculateUrl
qsWithOrderBy =
if (state[OrderBy]? <> null) then
qsWithSelect & [ #"$orderby" = state[OrderBy] ]
else
qsWithSelect,
Table.RowCount kezelése a GetRowCount használatával
A többi implementálható lekérdezéskezelővel ellentétben a GetRowCount
kezelő egyetlen értéket ad vissza – az eredményhalmazban várt sorok számát. Egy M lekérdezésben ez az érték általában a Table.RowCount átalakítás eredménye.
Az OData-lekérdezések részeként többféleképpen is kezelheti ezt az értéket:
- A $count lekérdezési paraméter, amely az eredményhalmaz külön mezőjeként adja vissza a darabszámot.
- A /$count elérési útszakasz, amely csak a teljes számot adja vissza skaláris értékként.
A lekérdezési paraméter megközelítésének hátránya, hogy a teljes lekérdezést továbbra is el kell küldenie az OData szolgáltatásnak. Mivel a szám az eredményhalmaz részeként visszakerül a beágyazottba, az eredményhalmaz első adatoldalát kell feldolgoznia. Bár ez a folyamat még mindig hatékonyabb, mint a teljes eredményhalmaz beolvasása és a sorok számlálása, valószínűleg még mindig több munka, mint amennyit el szeretne végezni.
Az elérésiút-szegmens megközelítésének előnye, hogy csak egyetlen skaláris értéket kap az eredményben. Ez a megközelítés sokkal hatékonyabbá teszi az egész műveletet. Az OData-specifikációban leírtak szerint azonban a /$count elérésiút-szegmens hibát ad vissza, ha más lekérdezési paramétereket is tartalmaz, például $top
vagy $skip
, amelyek korlátozzák annak hasznosságát.
Ebben az oktatóanyagban az GetRowCount
elérésiút-szegmens megközelítésével implementálta a kezelőt. Annak érdekében, hogy elkerülje azokat a hibákat, amelyeket más lekérdezési paraméterek hozzáadásakor kap, más állapotértékeket is ellenőriz, és ha nem talált ilyen hibát, "nem sikerült hibát" (...
) adott vissza. Ha hibát ad vissza a Table.View kezelőtől, az azt jelzi az M motornak, hogy a művelet nem hajtható végre, és inkább az alapértelmezett kezelőre kell visszaesnie (ami ebben az esetben a sorok teljes számát számolná).
Először adjon hozzá egy egységtesztet:
// GetRowCount
Fact("Fold $count", 15, Table.RowCount(Airlines)),
Mivel az /$count
elérésiút-szegmens JSON-eredménykészlet helyett egyetlen értéket ad vissza (egyszerű/szöveges formátumban), új belső függvényt (TripPin.Scalar
) is hozzá kell adnia a kérés elkészítéséhez és az eredmény kezeléséhez.
// 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;
Az implementáció ezt a függvényt használja (ha nem található más lekérdezési paraméter a state
következőben):
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,
A CalculateUrl
függvény úgy frissül, hogy hozzáfűzze /$count
az URL-címet, ha a RowCountOnly
mező be van állítva a 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,
Az új Table.RowCount
egységtesztnek most meg kell felelnie.
A tartalék eset teszteléséhez adjon hozzá egy másik tesztet, amely kényszeríti a hibát.
Először adjon hozzá egy segédmetódust, amely ellenőrzi a try
művelet eredményét egy összecsukási hiba esetén.
// 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;
Ezután adjon hozzá egy olyan tesztet, amely a Table.RowCount és a Table.FirstN függvényt is használja a hiba kényszerítéséhez.
// 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)))),
Fontos megjegyezni, hogy ez a teszt most hibát ad vissza, ha az összecsukási hiba értéke be van állítva false
, mert a Table.RowCount
művelet visszakerül a helyi (alapértelmezett) kezelőre. A tesztek futtatása az összecsukási hiba beállítással true
sikertelennek, Table.RowCount
és lehetővé teszi a teszt sikerességét.
Összegzés
Az összekötő Table.View implementálása jelentősen összetettebbé teszi a kódot. Mivel az M motor képes az összes átalakítás helyi feldolgozására, a Table.View kezelők hozzáadása nem teszi lehetővé az új forgatókönyveket a felhasználók számára, de hatékonyabb feldolgozást (és potenciálisan boldogabb felhasználókat) eredményez. A Table.View kezelők opcionális használatának egyik fő előnye, hogy lehetővé teszi az új funkciók növekményes hozzáadását anélkül, hogy az hatással lenne az összekötő visszamenőleges kompatibilitására.
A legtöbb összekötő esetében egy fontos (és alapszintű) kezelőt kell implementálni OnTake
(amely az OData-ban lefordítva $top
), mivel korlátozza a visszaadott sorok számát. A Power Query-élmény mindig sorokat OnTake
1000
hajt végre, amikor előnézeteket jelenít meg a kezelőben és a lekérdezésszerkesztőben, így a felhasználók jelentős teljesítménybeli javulást tapasztalhatnak a nagyobb adatkészletek használatakor.